mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 19:36:35 +08:00
addrenv interface changes: up_addrenv_create() may need to create .text and .bss/.data separately because of differing access privileges (read/execute vs read/write). And, as a consequence, up_addrenv_vaddr() needs to be split into up_addrenv_vtext(0 and up_addrenv_vdata().
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
<h1><big><font color="#3c34ec">
|
<h1><big><font color="#3c34ec">
|
||||||
<i>NuttX RTOS Porting Guide</i>
|
<i>NuttX RTOS Porting Guide</i>
|
||||||
</font></big></h1>
|
</font></big></h1>
|
||||||
<p>Last Updated: August 22, 2014</p>
|
<p>Last Updated: August 24, 2014</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -108,12 +108,13 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<a href="#up_addrenv_create">4.4.1 <code>up_addrenv_create()</code></a></br>
|
<a href="#up_addrenv_create">4.4.1 <code>up_addrenv_create()</code></a></br>
|
||||||
<a href="#up_addrenv_destroy">4.4.2 <code>up_addrenv_destroy()</code></a></br>
|
<a href="#up_addrenv_destroy">4.4.2 <code>up_addrenv_destroy()</code></a></br>
|
||||||
<a href="#up_addrenv_vaddr">4.4.3 <code>up_addrenv_vaddr()</code></a></br>
|
<a href="#up_addrenv_vtext">4.4.3 <code>up_addrenv_vtext()</code></a></br>
|
||||||
<a href="#up_addrenv_select">4.4.4 <code>up_addrenv_select()</code></a></br>
|
<a href="#up_addrenv_vdata">4.4.4 <code>up_addrenv_vdata()</code></a></br>
|
||||||
<a href="#up_addrenv_restore">4.4.5 <code>up_addrenv_restore()</code></a></br>
|
<a href="#up_addrenv_select">4.4.5 <code>up_addrenv_select()</code></a></br>
|
||||||
<a href="#up_addrenv_assign">4.4.6 <code>up_addrenv_assign()</code></a></br>
|
<a href="#up_addrenv_restore">4.4.6 <code>up_addrenv_restore()</code></a></br>
|
||||||
<a href="#up_addrenv_attach">4.4.7 <code>up_addrenv_attach()</code></a></br>
|
<a href="#up_addrenv_assign">4.4.7 <code>up_addrenv_assign()</code></a></br>
|
||||||
<a href="#up_addrenv_detach">4.4.8 <code>up_addrenv_detach()</code></a>
|
<a href="#up_addrenv_attach">4.4.8 <code>up_addrenv_attach()</code></a></br>
|
||||||
|
<a href="#up_addrenv_detach">4.4.9 <code>up_addrenv_detach()</code></a>
|
||||||
</ul>
|
</ul>
|
||||||
<a href="#exports">4.5 APIs Exported by NuttX to Architecture-Specific Logic</a>
|
<a href="#exports">4.5 APIs Exported by NuttX to Architecture-Specific Logic</a>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -2943,19 +2944,23 @@ VxWorks provides the following comparable interface:
|
|||||||
Destroy an address environment.
|
Destroy an address environment.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#up_addrenv_vaddr">4.4.3 <code>up_addrenv_vaddr()</code></a>:
|
<a href="#up_addrenv_vtext">4.4.3 <code>up_addrenv_vtext()</code></a>:
|
||||||
Returns the virtual base address of the address environment.
|
Returns the virtual base address of the <code>.text</code> address environment.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#up_addrenv_select">4.4.4 <code>up_addrenv_select()</code></a>:
|
<a href="#up_addrenv_vdata">4.4.4 <code>up_addrenv_vdata()</code></a>:
|
||||||
|
Returns the virtual base address of the <code>.bss</code>/<code>.data</code> address environment.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#up_addrenv_select">4.4.5 <code>up_addrenv_select()</code></a>:
|
||||||
Instantiate an address environment.
|
Instantiate an address environment.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#up_addrenv_restore">4.4.5 <code>up_addrenv_restore()</code></a>:
|
<a href="#up_addrenv_restore">4.4.6 <code>up_addrenv_restore()</code></a>:
|
||||||
Restore an address environment.
|
Restore an address environment.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#up_addrenv_assign">4.4.6 <code>up_addrenv_assign()</code></a>:
|
<a href="#up_addrenv_assign">4.4.7 <code>up_addrenv_assign()</code></a>:
|
||||||
Assign an address environment to a thread.
|
Assign an address environment to a thread.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -2968,12 +2973,12 @@ VxWorks provides the following comparable interface:
|
|||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a href="#up_addrenv_attach">4.4.7 <code>up_addrenv_attach()</code></a>:
|
<a href="#up_addrenv_attach">4.4.8 <code>up_addrenv_attach()</code></a>:
|
||||||
Clone the group address environment assigned to a new thread.
|
Clone the group address environment assigned to a new thread.
|
||||||
This operation is done when a pthread is created that share's the same address environment.
|
This operation is done when a pthread is created that share's the same address environment.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#up_addrenv_detach">4.4.8 <code>up_addrenv_detach()</code></a>:
|
<a href="#up_addrenv_detach">4.4.9 <code>up_addrenv_detach()</code></a>:
|
||||||
Release the thread's reference to a group address environment when a task/thread exits.
|
Release the thread's reference to a group address environment when a task/thread exits.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -2983,7 +2988,7 @@ VxWorks provides the following comparable interface:
|
|||||||
<h3><a name="up_addrenv_create">4.4.1 <code>up_addrenv_create()</code></a></h3>
|
<h3><a name="up_addrenv_create">4.4.1 <code>up_addrenv_create()</code></a></h3>
|
||||||
<p><b>Function Prototype</b>:</p>
|
<p><b>Function Prototype</b>:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<code>int up_addrenv_create(size_t envsize, FAR group_addrenv_t *addrenv);</code>
|
<code>int up_addrenv_create(size_t textsize, size_t datasize, FAR group_addrenv_t *addrenv);</code>
|
||||||
</ul>
|
</ul>
|
||||||
<p><b>Description</b>:</p>
|
<p><b>Description</b>:</p>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -2992,7 +2997,8 @@ VxWorks provides the following comparable interface:
|
|||||||
</ul>
|
</ul>
|
||||||
<p><b>Input Parameters</b>:</p>
|
<p><b>Input Parameters</b>:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>envsize</code>: The size (in bytes) of the address environment needed by the task.</li>
|
<li><code>textsize</code>: The size (in bytes) of the <code>.text</code> address environment needed by the task. This region may be read/execute only.</li>
|
||||||
|
<li><code>datasize</code>: The size (in bytes) of the <code>.bss/.data</code> address environment needed by the task. This region may be read/write only.</li>
|
||||||
<li><code>addrenv</code>: The location to return the representation of the task address environment.</li>
|
<li><code>addrenv</code>: The location to return the representation of the task address environment.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p><b>Returned Value</b>:</p>
|
<p><b>Returned Value</b>:</p>
|
||||||
@@ -3018,27 +3024,48 @@ VxWorks provides the following comparable interface:
|
|||||||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a name="up_addrenv_vaddr">4.4.3 <code>up_addrenv_vaddr()</code></a></h3>
|
<h3><a name="up_addrenv_vtext">4.4.3 <code>up_addrenv_vtext()</code></a></h3>
|
||||||
<p><b>Function Prototype</b>:<p>
|
<p><b>Function Prototype</b>:<p>
|
||||||
<ul>
|
<ul>
|
||||||
<code>int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr);</code>
|
<code>int up_addrenv_vtext(FAR group_addrenv_t addrenv, FAR void **vtext);</code>
|
||||||
</ul>
|
</ul>
|
||||||
<p><b>Description</b>:</p>
|
<p><b>Description</b>:</p>
|
||||||
<ul>
|
<ul>
|
||||||
Return the virtual address associated with the newly create address environment.
|
Return the virtual <code>.text</code> address associated with the newly create address environment.
|
||||||
This function is used by the binary loaders in order get an address that can be used to initialize the new task.
|
This function is used by the binary loaders in order get an address that can be used to initialize the new task.
|
||||||
</ul>
|
</ul>
|
||||||
<p><b>Input Parameters</b>:</p>
|
<p><b>Input Parameters</b>:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>addrenv</code>: The representation of the task address environment previously returned by up_addrenv_create.</li>
|
<li><code>addrenv</code>: The representation of the task address environment previously returned by up_addrenv_create.</li>
|
||||||
<li><code>vaddr</code>: The location to return the virtual address.</li>
|
<li><code>vtext</code>: The location to return the virtual address.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p><b>Returned Value</b>:</p>
|
<p><b>Returned Value</b>:</p>
|
||||||
<ul>
|
<ul>
|
||||||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a name="up_addrenv_select">4.4.4 <code>up_addrenv_select()</code></a></h3>
|
<h3><a name="up_addrenv_vdata">4.4.4 <code>up_addrenv_vdata()</code></a></h3>
|
||||||
|
<p><b>Function Prototype</b>:<p>
|
||||||
|
<ul>
|
||||||
|
<code>int up_addrenv_vdata(FAR group_addrenv_t addrenv, size_t textsize, FAR void **vdata);</code>
|
||||||
|
</ul>
|
||||||
|
<p><b>Description</b>:</p>
|
||||||
|
<ul>
|
||||||
|
Return the virtual <code>.text</code> address associated with the newly create address environment.
|
||||||
|
This function is used by the binary loaders in order get an address that can be used to initialize the new task.
|
||||||
|
</ul>
|
||||||
|
<p><b>Input Parameters</b>:</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>addrenv</code>: The representation of the task address environment previously returned by up_addrenv_create.</li>
|
||||||
|
<li><code>textsize</code>: For some implementations, the text and data will be saved in the same memory region (read/write/execute) and, in this case, the virtual address of the data just lies at this offset into the common region.</li>
|
||||||
|
<li><code>vdata</code>: The location to return the virtual address.</li>
|
||||||
|
</ul>
|
||||||
|
<p><b>Returned Value</b>:</p>
|
||||||
|
<ul>
|
||||||
|
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3><a name="up_addrenv_select">4.4.5 <code>up_addrenv_select()</code></a></h3>
|
||||||
<p><b>Function Prototype</b>:<p>
|
<p><b>Function Prototype</b>:<p>
|
||||||
<ul>
|
<ul>
|
||||||
<code>int up_addrenv_select(group_addrenv_t addrenv, save_addrenv_t *oldenv);</code>
|
<code>int up_addrenv_select(group_addrenv_t addrenv, save_addrenv_t *oldenv);</code>
|
||||||
@@ -3062,7 +3089,7 @@ VxWorks provides the following comparable interface:
|
|||||||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a name="up_addrenv_restore">4.4.5 <code>up_addrenv_restore()</code></a></h3>
|
<h3><a name="up_addrenv_restore">4.4.6 <code>up_addrenv_restore()</code></a></h3>
|
||||||
<p><b>Function Prototype</b>:<p>
|
<p><b>Function Prototype</b>:<p>
|
||||||
<ul>
|
<ul>
|
||||||
<code>int up_addrenv_restore(save_addrenv_t oldenv);</code>
|
<code>int up_addrenv_restore(save_addrenv_t oldenv);</code>
|
||||||
@@ -3081,10 +3108,10 @@ VxWorks provides the following comparable interface:
|
|||||||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a name="up_addrenv_assign">4.4.6 <code>up_addrenv_assign()</code></a></h3>
|
<h3><a name="up_addrenv_assign">4.4.7 <code>up_addrenv_assign()</code></a></h3>
|
||||||
<p><b>Function Prototype</b>:<p>
|
<p><b>Function Prototype</b>:<p>
|
||||||
<ul>
|
<ul>
|
||||||
<code>int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group);</code>
|
<code>int up_addrenv_assign(FAR const group_addrenv_t *addrenv, FAR struct task_group_s *group);</code>
|
||||||
</ul>
|
</ul>
|
||||||
<p><b>Description</b>:</p>
|
<p><b>Description</b>:</p>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -3100,7 +3127,7 @@ VxWorks provides the following comparable interface:
|
|||||||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a name="up_addrenv_attach">4.4.7 <code>up_addrenv_attach()</code></a></h3>
|
<h3><a name="up_addrenv_attach">4.4.8 <code>up_addrenv_attach()</code></a></h3>
|
||||||
<p><b>Function Prototype</b>:<p>
|
<p><b>Function Prototype</b>:<p>
|
||||||
<ul>
|
<ul>
|
||||||
<code>int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb);</code>
|
<code>int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb);</code>
|
||||||
@@ -3126,7 +3153,7 @@ VxWorks provides the following comparable interface:
|
|||||||
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3><a name="up_addrenv_detach">4.4.8 <code>up_addrenv_detach()</code></a></h3>
|
<h3><a name="up_addrenv_detach">4.4.9 <code>up_addrenv_detach()</code></a></h3>
|
||||||
<p><b>Function Prototype</b>:<p>
|
<p><b>Function Prototype</b>:<p>
|
||||||
<ul>
|
<ul>
|
||||||
<code>int up_addrenv_detach(FAR struct task_group_s *group, FAR struct task_group_s *tcb);</code>
|
<code>int up_addrenv_detach(FAR struct task_group_s *group, FAR struct task_group_s *tcb);</code>
|
||||||
|
|||||||
@@ -42,8 +42,10 @@
|
|||||||
*
|
*
|
||||||
* up_addrenv_create - Create an address environment
|
* up_addrenv_create - Create an address environment
|
||||||
* up_addrenv_destroy - Destroy an address environment.
|
* up_addrenv_destroy - Destroy an address environment.
|
||||||
* up_addrenv_vaddr - Returns the virtual base address of the address
|
* up_addrenv_vtext - Returns the virtual base address of the .text
|
||||||
* environment
|
* address environment
|
||||||
|
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
|
||||||
|
* address environment
|
||||||
* up_addrenv_select - Instantiate an address environment
|
* up_addrenv_select - Instantiate an address environment
|
||||||
* up_addrenv_restore - Restore an address environment
|
* up_addrenv_restore - Restore an address environment
|
||||||
* up_addrenv_assign - Assign an address environment to a group
|
* up_addrenv_assign - Assign an address environment to a group
|
||||||
@@ -67,6 +69,7 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
@@ -102,8 +105,10 @@
|
|||||||
* memory for the new task.
|
* memory for the new task.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* envsize - The size (in bytes) of the address environment needed by the
|
* textsize - The size (in bytes) of the .text address environment needed
|
||||||
* task.
|
* by the task. This region may be read/execute only.
|
||||||
|
* datasize - The size (in bytes) of the .data/.bss address environment
|
||||||
|
* needed by the task. This region may be read/write only.
|
||||||
* addrenv - The location to return the representation of the task address
|
* addrenv - The location to return the representation of the task address
|
||||||
* environment.
|
* environment.
|
||||||
*
|
*
|
||||||
@@ -112,7 +117,8 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int up_addrenv_create(size_t envsize, FAR group_addrenv_t *addrenv)
|
int up_addrenv_create(size_t textsize, size_t datasize,
|
||||||
|
FAR group_addrenv_t *addrenv)
|
||||||
{
|
{
|
||||||
#warning Missing logic
|
#warning Missing logic
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
@@ -141,27 +147,62 @@ int up_addrenv_destroy(group_addrenv_t addrenv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_addrenv_vaddr
|
* Name: up_addrenv_vtext
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Return the virtual address associated with the newly create address
|
* Return the virtual address associated with the newly create .text
|
||||||
* environment. This function is used by the binary loaders in order
|
* address environment. This function is used by the binary loaders in
|
||||||
* get an address that can be used to initialize the new task.
|
* order get an address that can be used to initialize the new task.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* addrenv - The representation of the task address environment previously
|
* addrenv - The representation of the task address environment previously
|
||||||
* returned by up_addrenv_create.
|
* returned by up_addrenv_create.
|
||||||
* vaddr - The location to return the virtual address.
|
* vtext - The location to return the virtual address.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr)
|
int up_addrenv_vtext(FAR group_addrenv_t addrenv, FAR void **vtext)
|
||||||
{
|
{
|
||||||
#warning Missing logic
|
/* Not much to do in this case */
|
||||||
return -ENOSYS;
|
|
||||||
|
DEBUGASSERT(addrenv && vtext);
|
||||||
|
*vtext = (FAR void *)CONFIG_ARCH_TEXT_VBASE;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_addrenv_vdata
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return the virtual address associated with the newly create .text
|
||||||
|
* address environment. This function is used by the binary loaders in
|
||||||
|
* order get an address that can be used to initialize the new task.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* addrenv - The representation of the task address environment previously
|
||||||
|
* returned by up_addrenv_create.
|
||||||
|
* textsize - For some implementations, the text and data will be saved
|
||||||
|
* in the same memory region (read/write/execute) and, in this case,
|
||||||
|
* the virtual address of the data just lies at this offset into the
|
||||||
|
* common region.
|
||||||
|
* vdata - The location to return the virtual address.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int up_addrenv_vdata(FAR group_addrenv_t addrenv, uintptr_t textsize,
|
||||||
|
FAR void **vdata)
|
||||||
|
{
|
||||||
|
/* Not much to do in this case */
|
||||||
|
|
||||||
|
DEBUGASSERT(addrenv && vdata);
|
||||||
|
*vdata = (FAR void *)CONFIG_ARCH_DATA_VBASE;
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -181,8 +222,8 @@ int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr)
|
|||||||
* The address environment that was in place before up_addrenv_select().
|
* The address environment that was in place before up_addrenv_select().
|
||||||
* This may be used with up_addrenv_restore() to restore the original
|
* This may be used with up_addrenv_restore() to restore the original
|
||||||
* address environment that was in place before up_addrenv_select() was
|
* address environment that was in place before up_addrenv_select() was
|
||||||
* called. Note that this may be a task agnostic, hardware
|
* called. Note that this may be a task agnostic, platform-specific
|
||||||
* representation that is different from group_addrenv_t.
|
* representation that may or may not be different from group_addrenv_t.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
@@ -204,7 +245,7 @@ int up_addrenv_select(group_addrenv_t addrenv, save_addrenv_t *oldenv)
|
|||||||
* original address environment.
|
* original address environment.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* oldenv - The hardware representation of the address environment
|
* oldenv - The platform-specific representation of the address environment
|
||||||
* previously returned by up_addrenv_select.
|
* previously returned by up_addrenv_select.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -234,10 +275,15 @@ int up_addrenv_restore(save_addrenv_t oldenv)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group)
|
int up_addrenv_assign(FAR const group_addrenv_t *addrenv,
|
||||||
|
FAR struct task_group_s *group)
|
||||||
{
|
{
|
||||||
#warning Missing logic
|
DEBUGASSERT(addrenv && group);
|
||||||
return -ENOSYS;
|
|
||||||
|
/* Just copy the addess environment into the group */
|
||||||
|
|
||||||
|
memcpy(&group->addrenv, addrenv, sizeof(group_addrenv_t));
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -263,8 +309,9 @@ int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group)
|
|||||||
|
|
||||||
int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
|
int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
|
||||||
{
|
{
|
||||||
#warning Missing logic
|
/* Nothing needs to be done in this implementation */
|
||||||
return -ENOSYS;
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -293,8 +340,9 @@ int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
|
|||||||
|
|
||||||
int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
|
int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
|
||||||
{
|
{
|
||||||
#warning Missing logic
|
/* Nothing needs to be done in this implementation */
|
||||||
return -ENOSYS;
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_ARCH_ADDRENV */
|
#endif /* CONFIG_ARCH_ADDRENV */
|
||||||
|
|||||||
@@ -186,8 +186,10 @@ return g_physhandle ? OK : -ENOMEM;
|
|||||||
*
|
*
|
||||||
* up_addrenv_create - Create an address environment
|
* up_addrenv_create - Create an address environment
|
||||||
* up_addrenv_destroy - Destroy an address environment.
|
* up_addrenv_destroy - Destroy an address environment.
|
||||||
* up_addrenv_vaddr - Returns the virtual base address of the address
|
* up_addrenv_vtext - Returns the virtual base address of the .text
|
||||||
* environment
|
* address environment
|
||||||
|
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
|
||||||
|
* address environment
|
||||||
* up_addrenv_select - Instantiate an address environment
|
* up_addrenv_select - Instantiate an address environment
|
||||||
* up_addrenv_restore - Restore an address environment
|
* up_addrenv_restore - Restore an address environment
|
||||||
* up_addrenv_assign - Assign an address environment to a group
|
* up_addrenv_assign - Assign an address environment to a group
|
||||||
@@ -214,8 +216,10 @@ return g_physhandle ? OK : -ENOMEM;
|
|||||||
* memory for the new task.
|
* memory for the new task.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* envsize - The size (in bytes) of the address environment needed by the
|
* textsize - The size (in bytes) of the .text address environment needed
|
||||||
* task.
|
* by the task. This region may be read/execute only.
|
||||||
|
* datasize - The size (in bytes) of the .data/.bss address environment
|
||||||
|
* needed by the task. This region may be read/write only.
|
||||||
* addrenv - The location to return the representation of the task address
|
* addrenv - The location to return the representation of the task address
|
||||||
* environment.
|
* environment.
|
||||||
*
|
*
|
||||||
@@ -224,17 +228,20 @@ return g_physhandle ? OK : -ENOMEM;
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int up_addrenv_create(size_t envsize, FAR group_addrenv_t *addrenv)
|
int up_addrenv_create(size_t textsize, size_t datasize,
|
||||||
|
FAR group_addrenv_t *addrenv)
|
||||||
{
|
{
|
||||||
FAR struct z180_cbr_s *cbr;
|
FAR struct z180_cbr_s *cbr;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
size_t envsize;
|
||||||
uintptr_t alloc;
|
uintptr_t alloc;
|
||||||
unsigned int npages;
|
unsigned int npages;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Convert the size from bytes to numbers of pages */
|
/* Convert the size from bytes to numbers of pages */
|
||||||
|
|
||||||
npages = PHYS_ALIGNUP(envsize);
|
envsize = textsize + datasize;
|
||||||
|
npages = PHYS_ALIGNUP(envsize);
|
||||||
if (npages < 1)
|
if (npages < 1)
|
||||||
{
|
{
|
||||||
/* No address environment... but I suppose that is not an error */
|
/* No address environment... but I suppose that is not an error */
|
||||||
@@ -331,28 +338,56 @@ int up_addrenv_destroy(group_addrenv_t addrenv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_addrenv_vaddr
|
* Name: up_addrenv_vtext
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Return the virtual address associated with the newly create address
|
* Return the virtual address associated with the newly create .text
|
||||||
* environment. This function is used by the binary loaders in order
|
* address environment. This function is used by the binary loaders in
|
||||||
* get an address that can be used to initialize the new task..
|
* order get an address that can be used to initialize the new task.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* addrenv - The representation of the task address environment previously
|
* addrenv - The representation of the task address environment previously
|
||||||
* returned by up_addrenv_create.
|
* returned by up_addrenv_create.
|
||||||
* vaddr - The location to return the virtual address.
|
* vtext - The location to return the virtual address.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr)
|
int up_addrenv_vtext(FAR group_addrenv_t addrenv, FAR void **vtext)
|
||||||
{
|
{
|
||||||
return CONFIG_Z180_COMMON1AREA_VIRTBASE;
|
return CONFIG_Z180_COMMON1AREA_VIRTBASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_addrenv_vdata
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return the virtual address associated with the newly create .text
|
||||||
|
* address environment. This function is used by the binary loaders in
|
||||||
|
* order get an address that can be used to initialize the new task.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* addrenv - The representation of the task address environment previously
|
||||||
|
* returned by up_addrenv_create.
|
||||||
|
* textsize - For some implementations, the text and data will be saved
|
||||||
|
* in the same memory region (read/write/execute) and, in this case,
|
||||||
|
* the virtual address of the data just lies at this offset into the
|
||||||
|
* common region.
|
||||||
|
* vdata - The location to return the virtual address.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int up_addrenv_vdata(FAR group_addrenv_t addrenv, uintptr_t textsize,
|
||||||
|
FAR void **vdata)
|
||||||
|
{
|
||||||
|
return CONFIG_Z180_COMMON1AREA_VIRTBASE + textsize;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_addrenv_select
|
* Name: up_addrenv_select
|
||||||
*
|
*
|
||||||
@@ -436,7 +471,8 @@ int up_addrenv_restore(save_addrenv_t oldenv)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group)
|
int up_addrenv_assign(FAR const group_addrenv_t *addrenv,
|
||||||
|
FAR struct task_group_s *group)
|
||||||
{
|
{
|
||||||
/* Make sure that there is no address environment in place on this TCB */
|
/* Make sure that there is no address environment in place on this TCB */
|
||||||
|
|
||||||
@@ -446,7 +482,7 @@ int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group)
|
|||||||
* special precautions should be needed.
|
* special precautions should be needed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
group->addrenv = addrenv;
|
group->addrenv = *addrenv;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -208,11 +208,11 @@ int exec_module(FAR const struct binary_s *binp)
|
|||||||
/* Assign the address environment to the new task group */
|
/* Assign the address environment to the new task group */
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
ret = up_addrenv_assign(binp->addrenv, tcb->cmn.group);
|
ret = up_addrenv_assign(&binp->addrenv, tcb->cmn.group);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
err = -ret;
|
err = -ret;
|
||||||
bdbg("up_addrenv_assign() failed: %d\n", ret);
|
bdbg("ERROR: up_addrenv_assign() failed: %d\n", ret);
|
||||||
goto errout_with_stack;
|
goto errout_with_stack;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+13
-9
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* binfmt/libelf/libelf.h
|
* binfmt/libelf/libelf.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -264,23 +264,27 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo);
|
|||||||
* Name: elf_addrenv_alloc
|
* Name: elf_addrenv_alloc
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate memory for the ELF image (elfalloc). If CONFIG_ARCH_ADDRENV=n,
|
* Allocate memory for the ELF image (textalloc and dataalloc). If
|
||||||
* elfalloc will be allocated using kzalloc(). If CONFIG_ARCH_ADDRENV-y, then
|
* CONFIG_ARCH_ADDRENV=n, textalloc will be allocated using kzalloc() and
|
||||||
* elfalloc will be allocated using up_addrenv_create(). In either case,
|
* dataalloc will be a offset from textalloc. If CONFIG_ARCH_ADDRENV-y, then
|
||||||
* there will be a unique instance of elfalloc (and stack) for each
|
* textalloc and dataalloc will be allocated using up_addrenv_create(). In
|
||||||
* instance of a process.
|
* either case, there will be a unique instance of textalloc and dataalloc
|
||||||
|
* (and stack) for each instance of a process.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* loadinfo - Load state information
|
* loadinfo - Load state information
|
||||||
* envsize - The size (in bytes) of the address environment needed for the
|
* textsize - The size (in bytes) of the .text address environment needed
|
||||||
* ELF image.
|
* for the ELF image (read/execute).
|
||||||
|
* datasize - The size (in bytes) of the .bss/.data address environment
|
||||||
|
* needed for the ELF image (read/write).
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t envsize);
|
int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
|
||||||
|
size_t datasize);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: elf_addrenv_select
|
* Name: elf_addrenv_select
|
||||||
|
|||||||
@@ -67,31 +67,36 @@
|
|||||||
* Name: elf_addrenv_alloc
|
* Name: elf_addrenv_alloc
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate memory for the ELF image (elfalloc). If CONFIG_ARCH_ADDRENV=n,
|
* Allocate memory for the ELF image (textalloc and dataalloc). If
|
||||||
* elfalloc will be allocated using kuzalloc(). If CONFIG_ARCH_ADDRENV-y, then
|
* CONFIG_ARCH_ADDRENV=n, textalloc will be allocated using kzalloc() and
|
||||||
* elfalloc will be allocated using up_addrenv_create(). In either case,
|
* dataalloc will be a offset from textalloc. If CONFIG_ARCH_ADDRENV-y, then
|
||||||
* there will be a unique instance of elfalloc (and stack) for each
|
* textalloc and dataalloc will be allocated using up_addrenv_create(). In
|
||||||
* instance of a process.
|
* either case, there will be a unique instance of textalloc and dataalloc
|
||||||
|
* (and stack) for each instance of a process.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* loadinfo - Load state information
|
* loadinfo - Load state information
|
||||||
* envsize - The size (in bytes) of the address environment needed for the
|
* textsize - The size (in bytes) of the .text address environment needed
|
||||||
* ELF image.
|
* for the ELF image (read/execute).
|
||||||
|
* datasize - The size (in bytes) of the .bss/.data address environment
|
||||||
|
* needed for the ELF image (read/write).
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t envsize)
|
int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
|
||||||
|
size_t datasize)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
FAR void *vaddr;
|
FAR void *vtext;
|
||||||
|
FAR void *vdata;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Create an address environment for the new ELF task */
|
/* Create an address environment for the new ELF task */
|
||||||
|
|
||||||
ret = up_addrenv_create(envsize, &loadinfo->addrenv);
|
ret = up_addrenv_create(textsize, datasize, &loadinfo->addrenv);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
bdbg("ERROR: up_addrenv_create failed: %d\n", ret);
|
bdbg("ERROR: up_addrenv_create failed: %d\n", ret);
|
||||||
@@ -104,24 +109,33 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t envsize)
|
|||||||
* selected.
|
* selected.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = up_addrenv_vaddr(loadinfo->addrenv, &vaddr);
|
ret = up_addrenv_vtext(loadinfo->addrenv, &vtext);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
bdbg("ERROR: up_addrenv_vaddr failed: %d\n", ret);
|
bdbg("ERROR: up_addrenv_vtext failed: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadinfo->elfalloc = (uintptr_t)vaddr;
|
ret = up_addrenv_vdata(loadinfo->addrenv, textsize, &vdata);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
bdbg("ERROR: up_adup_addrenv_vdatadrenv_vtext failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadinfo->textalloc = (uintptr_t)vaddr;
|
||||||
|
loadinfo->dataalloc = (uintptr_t)vdata;
|
||||||
return OK;
|
return OK;
|
||||||
#else
|
#else
|
||||||
/* Allocate memory to hold the ELF image */
|
/* Allocate memory to hold the ELF image */
|
||||||
|
|
||||||
loadinfo->elfalloc = (uintptr_t)kuzalloc(envsize);
|
loadinfo->textalloc = (uintptr_t)kuzalloc(textsize + datasize);
|
||||||
if (!loadinfo->elfalloc)
|
if (!loadinfo->textalloc)
|
||||||
{
|
{
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadinfo->dataalloc = loadinfo->textalloc + textsize;
|
||||||
return OK;
|
return OK;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -159,18 +173,22 @@ void elf_addrenv_free(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
/* Clear out all indications of the allocated address environment */
|
/* Clear out all indications of the allocated address environment */
|
||||||
|
|
||||||
loadinfo->elfalloc = 0;
|
loadinfo->textalloc = 0;
|
||||||
loadinfo->elfsize = 0;
|
loadinfo->dataalloc = 0;
|
||||||
loadinfo->addrenv = 0;
|
loadinfo->textsize = 0;
|
||||||
|
loadinfo->datasize = 0;
|
||||||
|
loadinfo->addrenv = 0;
|
||||||
#else
|
#else
|
||||||
/* If there is an allocation for the ELF image, free it */
|
/* If there is an allocation for the ELF image, free it */
|
||||||
|
|
||||||
if (loadinfo->elfalloc != 0)
|
if (loadinfo->textalloc != 0)
|
||||||
{
|
{
|
||||||
kufree((FAR void *)loadinfo->elfalloc);
|
kufree((FAR void *)loadinfo->textalloc);
|
||||||
loadinfo->elfalloc = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadinfo->elfsize = 0;
|
loadinfo->textalloc = 0;
|
||||||
|
loadinfo->dataalloc = 0;
|
||||||
|
loadinfo->textsize = 0;
|
||||||
|
loadinfo->datasize = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
|
|||||||
/* Flush the instruction cache before starting the newly loaded module */
|
/* Flush the instruction cache before starting the newly loaded module */
|
||||||
|
|
||||||
#ifdef CONFIG_ELF_ICACHE
|
#ifdef CONFIG_ELF_ICACHE
|
||||||
arch_flushicache((FAR void*)loadinfo->elfalloc, loadinfo->elfsize);
|
arch_flushicache((FAR void*)loadinfo->textalloc, loadinfo->textsize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -192,9 +192,10 @@ int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
FAR uintptr_t *ptr = (uintptr_t *)((FAR void *)(&loadinfo->ctors)[i]);
|
FAR uintptr_t *ptr = (uintptr_t *)((FAR void *)(&loadinfo->ctors)[i]);
|
||||||
|
|
||||||
bvdbg("ctor %d: %08lx + %08lx = %08lx\n",
|
bvdbg("ctor %d: %08lx + %08lx = %08lx\n",
|
||||||
i, *ptr, loadinfo->elfalloc, *ptr + loadinfo->elfalloc);
|
i, *ptr, (unsigned long)loadinfo->txtalloc,
|
||||||
|
(unsigned long)(*ptr + loadinfo->txtalloc));
|
||||||
|
|
||||||
*ptr += loadinfo->elfalloc;
|
*ptr += loadinfo->txtalloc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -192,9 +192,10 @@ int elf_loaddtors(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
FAR uintptr_t *ptr = (uintptr_t *)((FAR void *)(&loadinfo->dtors)[i]);
|
FAR uintptr_t *ptr = (uintptr_t *)((FAR void *)(&loadinfo->dtors)[i]);
|
||||||
|
|
||||||
bvdbg("dtor %d: %08lx + %08lx = %08lx\n",
|
bvdbg("dtor %d: %08lx + %08lx = %08lx\n",
|
||||||
i, *ptr, loadinfo->elfalloc, *ptr + loadinfo->elfalloc);
|
i, *ptr, (unsigned long)loadinfo->textalloc,
|
||||||
|
(unsigned long)(*ptr + loadinfo->textalloc));
|
||||||
|
|
||||||
*ptr += loadinfo->elfalloc;
|
*ptr += loadinfo->textalloc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
+47
-14
@@ -88,12 +88,15 @@
|
|||||||
|
|
||||||
static void elf_elfsize(struct elf_loadinfo_s *loadinfo)
|
static void elf_elfsize(struct elf_loadinfo_s *loadinfo)
|
||||||
{
|
{
|
||||||
size_t elfsize;
|
size_t textsize;
|
||||||
|
size_t datasize;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Accumulate the size each section into memory that is marked SHF_ALLOC */
|
/* Accumulate the size each section into memory that is marked SHF_ALLOC */
|
||||||
|
|
||||||
elfsize = 0;
|
textsize = 0;
|
||||||
|
datasize = 0;
|
||||||
|
|
||||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||||
{
|
{
|
||||||
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
FAR Elf32_Shdr *shdr = &loadinfo->shdr[i];
|
||||||
@@ -104,13 +107,25 @@ static void elf_elfsize(struct elf_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
if ((shdr->sh_flags & SHF_ALLOC) != 0)
|
if ((shdr->sh_flags & SHF_ALLOC) != 0)
|
||||||
{
|
{
|
||||||
elfsize += ELF_ALIGNUP(shdr->sh_size);
|
/* SHF_WRITE indicates that the section address space is write-
|
||||||
|
* able
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((shdr->sh_flags & SHF_WRITE) != 0)
|
||||||
|
{
|
||||||
|
datasize += ELF_ALIGNUP(shdr->sh_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textsize += ELF_ALIGNUP(shdr->sh_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the allocation size */
|
/* Save the allocation size */
|
||||||
|
|
||||||
loadinfo->elfsize = elfsize;
|
loadinfo->textsize = textsize;
|
||||||
|
loadinfo->datasize = datasize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -129,13 +144,15 @@ static void elf_elfsize(struct elf_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
||||||
{
|
{
|
||||||
FAR uint8_t *dest;
|
FAR uint8_t *text;
|
||||||
|
FAR uint8_t *data;
|
||||||
|
FAR uint8_t **pptr;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Allocate (and zero) memory for the ELF file. */
|
/* Allocate (and zero) memory for the ELF file. */
|
||||||
|
|
||||||
ret = elf_addrenv_alloc(loadinfo, loadinfo->elfsize);
|
ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
bdbg("ERROR: elf_addrenv_alloc() failed: %d\n", ret);
|
bdbg("ERROR: elf_addrenv_alloc() failed: %d\n", ret);
|
||||||
@@ -145,7 +162,8 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
/* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */
|
/* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */
|
||||||
|
|
||||||
bvdbg("Loaded sections:\n");
|
bvdbg("Loaded sections:\n");
|
||||||
dest = (FAR uint8_t*)loadinfo->elfalloc;
|
text = (FAR uint8_t*)loadinfo->textalloc;
|
||||||
|
data = (FAR uint8_t*)loadinfo->dataalloc;
|
||||||
|
|
||||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||||
{
|
{
|
||||||
@@ -165,8 +183,21 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
if (shdr->sh_type != SHT_NOBITS)
|
if (shdr->sh_type != SHT_NOBITS)
|
||||||
{
|
{
|
||||||
/* If CONFIG_ARCH_ADDRENV=y, then 'dest' lies in a virtual address space
|
/* SHF_WRITE indicates that the section address space is write-
|
||||||
* that may not be in place now. elf_addrenv_select() will
|
* able
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((shdr->sh_flags & SHF_WRITE) != 0)
|
||||||
|
{
|
||||||
|
pptr = &data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pptr = &text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If CONFIG_ARCH_ADDRENV=y, then 'text' lies in a virtual address
|
||||||
|
* space that may not be in place now. elf_addrenv_select() will
|
||||||
* temporarily instantiate that address space.
|
* temporarily instantiate that address space.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -179,9 +210,9 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Read the section data from sh_offset to dest */
|
/* Read the section data from sh_offset to the memory region */
|
||||||
|
|
||||||
ret = elf_read(loadinfo, dest, shdr->sh_size, shdr->sh_offset);
|
ret = elf_read(loadinfo, *pptr, shdr->sh_size, shdr->sh_offset);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
bdbg("Failed to read section %d: %d\n", i, ret);
|
bdbg("Failed to read section %d: %d\n", i, ret);
|
||||||
@@ -202,12 +233,14 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
/* Update sh_addr to point to copy in memory */
|
/* Update sh_addr to point to copy in memory */
|
||||||
|
|
||||||
bvdbg("%d. %08x->%08x\n", i, (long)shdr->sh_addr, (long)dest);
|
bvdbg("%d. %08lx->%08lx\n", i,
|
||||||
shdr->sh_addr = (uintptr_t)dest;
|
(unsigned long)shdr->sh_addr, (unsigned long)*pptr);
|
||||||
|
|
||||||
|
shdr->sh_addr = (uintptr_t)*pptr;
|
||||||
|
|
||||||
/* Setup the memory pointer for the next time through the loop */
|
/* Setup the memory pointer for the next time through the loop */
|
||||||
|
|
||||||
dest += ELF_ALIGNUP(shdr->sh_size);
|
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|||||||
@@ -59,11 +59,9 @@
|
|||||||
* Name: nxflat_addrenv_alloc
|
* Name: nxflat_addrenv_alloc
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate memory for the ELF image (elfalloc). If CONFIG_ARCH_ADDRENV=n,
|
* Allocate data memory for the NXFLAT image. If CONFIG_ARCH_ADDRENV=n,
|
||||||
* elfalloc will be allocated using kzalloc(). If CONFIG_ARCH_ADDRENV-y, then
|
* memory will be allocated using kzalloc(). If CONFIG_ARCH_ADDRENV-y,
|
||||||
* elfalloc will be allocated using up_addrenv_create(). In either case,
|
* then memory will be allocated using up_addrenv_create().
|
||||||
* there will be a unique instance of elfalloc (and stack) for each
|
|
||||||
* instance of a process.
|
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* loadinfo - Load state information
|
* loadinfo - Load state information
|
||||||
|
|||||||
@@ -68,11 +68,9 @@
|
|||||||
* Name: nxflat_addrenv_alloc
|
* Name: nxflat_addrenv_alloc
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate memory for the ELF image (elfalloc). If CONFIG_ARCH_ADDRENV=n,
|
* Allocate data memory for the NXFLAT image. If CONFIG_ARCH_ADDRENV=n,
|
||||||
* elfalloc will be allocated using kuzalloc(). If CONFIG_ARCH_ADDRENV-y, then
|
* memory will be allocated using kzalloc(). If CONFIG_ARCH_ADDRENV-y,
|
||||||
* elfalloc will be allocated using up_addrenv_create(). In either case,
|
* then memory will be allocated using up_addrenv_create().
|
||||||
* there will be a unique instance of elfalloc (and stack) for each
|
|
||||||
* instance of a process.
|
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* loadinfo - Load state information
|
* loadinfo - Load state information
|
||||||
@@ -88,7 +86,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
|
|||||||
{
|
{
|
||||||
FAR struct dspace_s *dspace;
|
FAR struct dspace_s *dspace;
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
FAR void *vaddr;
|
FAR void *vdata;
|
||||||
save_addrenv_t oldenv;
|
save_addrenv_t oldenv;
|
||||||
int ret;
|
int ret;
|
||||||
#endif
|
#endif
|
||||||
@@ -120,10 +118,10 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
|
|||||||
* selected.
|
* selected.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = up_addrenv_vaddr(loadinfo->addrenv, &vaddr);
|
ret = up_addrenv_vdata(loadinfo->addrenv, 0, &vdata);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
bdbg("ERROR: up_addrenv_vaddr failed: %d\n", ret);
|
bdbg("ERROR: up_addrenv_vdata failed: %d\n", ret);
|
||||||
goto errout_with_addrenv;
|
goto errout_with_addrenv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +136,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
|
|||||||
goto errout_with_addrenv;
|
goto errout_with_addrenv;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(vaddr, 0, envsize);
|
memset(vdata, 0, envsize);
|
||||||
|
|
||||||
ret = up_addrenv_restore(oldenv);
|
ret = up_addrenv_restore(oldenv);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -151,7 +149,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
|
|||||||
|
|
||||||
loadinfo->dspace = dspace;
|
loadinfo->dspace = dspace;
|
||||||
dspace->crefs = 1;
|
dspace->crefs = 1;
|
||||||
dspace->region = (FAR uint8_t *)vaddr;
|
dspace->region = (FAR uint8_t *)vdata;
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
errout_with_addrenv:
|
errout_with_addrenv:
|
||||||
|
|||||||
@@ -152,8 +152,10 @@
|
|||||||
*
|
*
|
||||||
* up_addrenv_create - Create an address environment
|
* up_addrenv_create - Create an address environment
|
||||||
* up_addrenv_destroy - Destroy an address environment.
|
* up_addrenv_destroy - Destroy an address environment.
|
||||||
* up_addrenv_vaddr - Returns the virtual base address of the address
|
* up_addrenv_vtext - Returns the virtual base address of the .text
|
||||||
* environment
|
* address environment
|
||||||
|
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
|
||||||
|
* address environment
|
||||||
* up_addrenv_select - Instantiate an address environment
|
* up_addrenv_select - Instantiate an address environment
|
||||||
* up_addrenv_restore - Restore an address environment
|
* up_addrenv_restore - Restore an address environment
|
||||||
* up_addrenv_assign - Assign an address environment to a group
|
* up_addrenv_assign - Assign an address environment to a group
|
||||||
|
|||||||
+45
-12
@@ -675,8 +675,10 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size);
|
|||||||
*
|
*
|
||||||
* up_addrenv_create - Create an address environment
|
* up_addrenv_create - Create an address environment
|
||||||
* up_addrenv_destroy - Destroy an address environment.
|
* up_addrenv_destroy - Destroy an address environment.
|
||||||
* up_addrenv_vaddr - Returns the virtual base address of the address
|
* up_addrenv_vtext - Returns the virtual base address of the .text
|
||||||
* environment
|
* address environment
|
||||||
|
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
|
||||||
|
* address environment
|
||||||
* up_addrenv_select - Instantiate an address environment
|
* up_addrenv_select - Instantiate an address environment
|
||||||
* up_addrenv_restore - Restore an address environment
|
* up_addrenv_restore - Restore an address environment
|
||||||
* up_addrenv_assign - Assign an address environment to a group
|
* up_addrenv_assign - Assign an address environment to a group
|
||||||
@@ -703,8 +705,10 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size);
|
|||||||
* memory for the new task.
|
* memory for the new task.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* envsize - The size (in bytes) of the address environment needed by the
|
* textsize - The size (in bytes) of the .text address environment needed
|
||||||
* task.
|
* by the task. This region may be read/execute only.
|
||||||
|
* datasize - The size (in bytes) of the .data/.bss address environment
|
||||||
|
* needed by the task. This region may be read/write only.
|
||||||
* addrenv - The location to return the representation of the task address
|
* addrenv - The location to return the representation of the task address
|
||||||
* environment.
|
* environment.
|
||||||
*
|
*
|
||||||
@@ -714,7 +718,8 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
int up_addrenv_create(size_t envsize, FAR group_addrenv_t *addrenv);
|
int up_addrenv_create(size_t textsize, size_t datasize,
|
||||||
|
FAR group_addrenv_t *addrenv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -738,17 +743,17 @@ int up_addrenv_destroy(group_addrenv_t addrenv);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_addrenv_vaddr
|
* Name: up_addrenv_vtext
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Return the virtual address associated with the newly create address
|
* Return the virtual address associated with the newly create .text
|
||||||
* environment. This function is used by the binary loaders in order
|
* address environment. This function is used by the binary loaders in
|
||||||
* get an address that can be used to initialize the new task.
|
* order get an address that can be used to initialize the new task.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* addrenv - The representation of the task address environment previously
|
* addrenv - The representation of the task address environment previously
|
||||||
* returned by up_addrenv_create.
|
* returned by up_addrenv_create.
|
||||||
* vaddr - The location to return the virtual address.
|
* vtext - The location to return the virtual address.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
@@ -756,7 +761,34 @@ int up_addrenv_destroy(group_addrenv_t addrenv);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr);
|
int up_addrenv_vtext(FAR group_addrenv_t addrenv, FAR void **vtext);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_addrenv_vdata
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return the virtual address associated with the newly create .text
|
||||||
|
* address environment. This function is used by the binary loaders in
|
||||||
|
* order get an address that can be used to initialize the new task.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* addrenv - The representation of the task address environment previously
|
||||||
|
* returned by up_addrenv_create.
|
||||||
|
* textsize - For some implementations, the text and data will be saved
|
||||||
|
* in the same memory region (read/write/execute) and, in this case,
|
||||||
|
* the virtual address of the data just lies at this offset into the
|
||||||
|
* common region.
|
||||||
|
* vdata - The location to return the virtual address.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
|
int up_addrenv_vdata(FAR group_addrenv_t addrenv, uintptr_t textsize,
|
||||||
|
FAR void **vdata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -826,7 +858,8 @@ int up_addrenv_restore(save_addrenv_t oldenv);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group);
|
int up_addrenv_assign(FAR const group_addrenv_t *addrenv,
|
||||||
|
FAR struct task_group_s *group);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -104,8 +104,10 @@ struct elf_loadinfo_s
|
|||||||
* the ELF module has been loaded.
|
* the ELF module has been loaded.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uintptr_t elfalloc; /* Memory allocated when ELF file was loaded */
|
uintptr_t textalloc; /* .text memory allocated when ELF file was loaded */
|
||||||
size_t elfsize; /* Size of the ELF memory allocation */
|
uintptr_t dataalloc; /* .bss/.data memory allocated when ELF file was loaded */
|
||||||
|
size_t textsize; /* Size of the ELF .text memory allocation */
|
||||||
|
size_t datasize; /* Size of the ELF .bss/.data memory allocation */
|
||||||
off_t filelen; /* Length of the entire ELF file */
|
off_t filelen; /* Length of the entire ELF file */
|
||||||
Elf32_Ehdr ehdr; /* Buffered ELF file header */
|
Elf32_Ehdr ehdr; /* Buffered ELF file header */
|
||||||
FAR Elf32_Shdr *shdr; /* Buffered ELF section headers */
|
FAR Elf32_Shdr *shdr; /* Buffered ELF section headers */
|
||||||
@@ -127,12 +129,12 @@ struct elf_loadinfo_s
|
|||||||
* addrenv - This is the handle created by up_addrenv_create() that can be
|
* addrenv - This is the handle created by up_addrenv_create() that can be
|
||||||
* used to manage the tasks address space.
|
* used to manage the tasks address space.
|
||||||
* oldenv - This is a value returned by up_addrenv_select() that must be
|
* oldenv - This is a value returned by up_addrenv_select() that must be
|
||||||
* used to restore the current hardware address environment.
|
* used to restore the current address environment.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
group_addrenv_t addrenv; /* Task group address environment */
|
group_addrenv_t addrenv; /* Task group address environment */
|
||||||
save_addrenv_t oldenv; /* Saved hardware address environment */
|
save_addrenv_t oldenv; /* Saved address environment */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint16_t symtabidx; /* Symbol table section index */
|
uint16_t symtabidx; /* Symbol table section index */
|
||||||
|
|||||||
@@ -99,12 +99,12 @@ struct nxflat_loadinfo_s
|
|||||||
* addrenv - This is the handle created by up_addrenv_create() that can be
|
* addrenv - This is the handle created by up_addrenv_create() that can be
|
||||||
* used to manage the tasks address space.
|
* used to manage the tasks address space.
|
||||||
* oldenv - This is a value returned by up_addrenv_select() that must be
|
* oldenv - This is a value returned by up_addrenv_select() that must be
|
||||||
* used to restore the current hardware address environment.
|
* used to restore the current address environment.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
group_addrenv_t addrenv; /* Task group address environment */
|
group_addrenv_t addrenv; /* Task group address environment */
|
||||||
save_addrenv_t oldenv; /* Saved hardware address environment */
|
save_addrenv_t oldenv; /* Saved address environment */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* File descriptors */
|
/* File descriptors */
|
||||||
|
|||||||
Reference in New Issue
Block a user