libnxflat_addrenv.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /****************************************************************************
  2. * binfmt/libnxflat/libnxflat_addrenv.c
  3. *
  4. * Copyright (C) 2012 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <string.h>
  40. #include <errno.h>
  41. #include <debug.h>
  42. #include <nuttx/arch.h>
  43. #include <nuttx/kmalloc.h>
  44. #include "libnxflat.h"
  45. /****************************************************************************
  46. * Pre-processor Definitions
  47. ****************************************************************************/
  48. #ifndef MIN
  49. # define MIN(x,y) ((x) < (y) ? (x) : (y))
  50. #endif
  51. /****************************************************************************
  52. * Private Constant Data
  53. ****************************************************************************/
  54. /****************************************************************************
  55. * Private Functions
  56. ****************************************************************************/
  57. /****************************************************************************
  58. * Public Functions
  59. ****************************************************************************/
  60. /****************************************************************************
  61. * Name: nxflat_addrenv_alloc
  62. *
  63. * Description:
  64. * Allocate data memory for the NXFLAT image. If CONFIG_ARCH_ADDRENV=n,
  65. * memory will be allocated using kmm_zalloc(). If CONFIG_ARCH_ADDRENV-y,
  66. * then memory will be allocated using up_addrenv_create().
  67. *
  68. * Input Parameters:
  69. * loadinfo - Load state information
  70. * envsize - The size (in bytes) of the address environment needed for the
  71. * ELF image.
  72. *
  73. * Returned Value:
  74. * Zero (OK) on success; a negated errno value on failure.
  75. *
  76. ****************************************************************************/
  77. int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
  78. {
  79. FAR struct dspace_s *dspace;
  80. #ifdef CONFIG_ARCH_ADDRENV
  81. FAR void *vdata;
  82. save_addrenv_t oldenv;
  83. size_t heapsize;
  84. int ret;
  85. #endif
  86. DEBUGASSERT(!loadinfo->dspace);
  87. /* Allocate the struct dspace_s container for the D-Space allocation */
  88. dspace = (FAR struct dspace_s *)kmm_malloc(sizeof(struct dspace_s));
  89. if (dspace == 0)
  90. {
  91. berr("ERROR: Failed to allocate DSpace\n");
  92. return -ENOMEM;
  93. }
  94. #ifdef CONFIG_ARCH_ADDRENV
  95. /* Determine the heapsize to allocate. If there is no dynamic stack then
  96. * heapsize must at least as big as the fixed stack size since the stack
  97. * will be allocated from the heap in that case.
  98. */
  99. #ifdef CONFIG_ARCH_STACK_DYNAMIC
  100. heapsize = ARCH_HEAP_SIZE;
  101. #else
  102. heapsize = MIN(loadinfo->stacksize, ARCH_HEAP_SIZE);
  103. #endif
  104. /* Create a D-Space address environment for the new NXFLAT task */
  105. ret = up_addrenv_create(0, envsize, heapsize, &loadinfo->addrenv);
  106. if (ret < 0)
  107. {
  108. berr("ERROR: up_addrenv_create failed: %d\n", ret);
  109. goto errout_with_dspace;
  110. }
  111. /* Get the virtual address associated with the start of the address
  112. * environment. This is the base address that we will need to use to
  113. * access the D-Space region (but only if the address environment has been
  114. * selected.
  115. */
  116. ret = up_addrenv_vdata(&loadinfo->addrenv, 0, &vdata);
  117. if (ret < 0)
  118. {
  119. berr("ERROR: up_addrenv_vdata failed: %d\n", ret);
  120. goto errout_with_addrenv;
  121. }
  122. /* Clear all of the allocated D-Space memory. We have to temporarily
  123. * selected the D-Space address environment to do this.
  124. */
  125. ret = up_addrenv_select(loadinfo->addrenv, &oldenv);
  126. if (ret < 0)
  127. {
  128. berr("ERROR: up_addrenv_select failed: %d\n", ret);
  129. goto errout_with_addrenv;
  130. }
  131. memset(vdata, 0, envsize);
  132. ret = up_addrenv_restore(oldenv);
  133. if (ret < 0)
  134. {
  135. berr("ERROR: up_addrenv_restore failed: %d\n", ret);
  136. goto errout_with_addrenv;
  137. }
  138. /* Success... save the fruits of our labor */
  139. loadinfo->dspace = dspace;
  140. dspace->crefs = 1;
  141. dspace->region = (FAR uint8_t *)vdata;
  142. return OK;
  143. errout_with_addrenv:
  144. up_addrenv_destroy(&loadinfo->addrenv);
  145. loadinfo->addrenv = 0;
  146. errout_with_dspace:
  147. kmm_free(dspace);
  148. return ret;
  149. #else
  150. /* Allocate (and zero) memory to hold the ELF image */
  151. dspace->region = (FAR uint8_t *)kumm_zalloc(envsize);
  152. if (!dspace->region)
  153. {
  154. kmm_free(dspace);
  155. return -ENOMEM;
  156. }
  157. loadinfo->dspace = dspace;
  158. dspace->crefs = 1;
  159. return OK;
  160. #endif
  161. }
  162. /****************************************************************************
  163. * Name: nxflat_addrenv_free
  164. *
  165. * Description:
  166. * Release the address environment previously created by
  167. * nxflat_addrenv_create(). This function is called only under certain
  168. * error conditions after the module has been loaded but not yet
  169. * started. After the module has been started, the address environment
  170. * will automatically be freed when the module exits.
  171. *
  172. * Input Parameters:
  173. * loadinfo - Load state information
  174. *
  175. * Returned Value:
  176. * None.
  177. *
  178. ****************************************************************************/
  179. void nxflat_addrenv_free(FAR struct nxflat_loadinfo_s *loadinfo)
  180. {
  181. FAR struct dspace_s *dspace;
  182. #ifdef CONFIG_ARCH_ADDRENV
  183. int ret;
  184. #endif
  185. DEBUGASSERT(loadinfo);
  186. dspace = loadinfo->dspace;
  187. if (dspace)
  188. {
  189. #ifdef CONFIG_ARCH_ADDRENV
  190. /* Destroy the address environment */
  191. ret = up_addrenv_destroy(loadinfo->addrenv);
  192. if (ret < 0)
  193. {
  194. berr("ERROR: up_addrenv_destroy failed: %d\n", ret);
  195. }
  196. loadinfo->addrenv = 0;
  197. #else
  198. /* Free the allocated D-Space region */
  199. if (dspace->region)
  200. {
  201. kumm_free(dspace->region);
  202. }
  203. #endif
  204. /* Now destroy the D-Space container */
  205. DEBUGASSERT(dspace->crefs == 1);
  206. kmm_free(dspace);
  207. loadinfo->dspace = NULL;
  208. }
  209. }