module.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. /*
  2. * File : module.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2010-01-09 Bernard first version
  13. * 2010-04-09 yi.qiu implement based on first version
  14. */
  15. #include <rtthread.h>
  16. #include <rtm.h>
  17. #include "string.h"
  18. #include "kservice.h"
  19. /* #define RT_MODULE_DEBUG */
  20. #ifdef RT_USING_MODULE
  21. #include "module.h"
  22. #define elf_module ((Elf32_Ehdr *)module_ptr)
  23. #define shdr ((Elf32_Shdr *)((rt_uint8_t *)module_ptr + elf_module->e_shoff))
  24. #define phdr ((Elf32_Phdr *)((rt_uint8_t *)module_ptr + elf_module->e_phoff))
  25. #define IS_PROG(s) (s.sh_type == SHT_PROGBITS)
  26. #define IS_NOPROG(s) (s.sh_type == SHT_NOBITS)
  27. #define IS_REL(s) (s.sh_type == SHT_REL)
  28. #define IS_RELA(s) (s.sh_type == SHT_RELA)
  29. #define IS_ALLOC(s) (s.sh_flags == SHF_ALLOC)
  30. #define IS_AX(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_EXECINSTR))
  31. #define IS_AW(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_WRITE))
  32. static struct rt_module* rt_current_module = RT_NULL;
  33. /**
  34. * This function will return self module object
  35. *
  36. * @return the self module object
  37. *
  38. */
  39. rt_module_t rt_module_self (void)
  40. {
  41. /* return current module */
  42. return rt_current_module;
  43. }
  44. /**
  45. * This function will set current module object
  46. *
  47. * @return RT_EOK
  48. */
  49. rt_err_t rt_module_set (rt_module_t module)
  50. {
  51. /* set current module */
  52. rt_current_module = module;
  53. return RT_EOK;
  54. }
  55. static int rt_module_arm_relocate(struct rt_module* module, Elf32_Rel *rel, Elf32_Addr sym_val)
  56. {
  57. Elf32_Addr *where, tmp;
  58. Elf32_Sword addend;
  59. where = (Elf32_Addr *)((rt_uint8_t*)module->module_space + rel->r_offset);
  60. switch (ELF32_R_TYPE(rel->r_info))
  61. {
  62. case R_ARM_NONE:
  63. break;
  64. case R_ARM_ABS32:
  65. *where += (Elf32_Addr)sym_val;
  66. #ifdef RT_MODULE_DEBUG
  67. rt_kprintf("R_ARM_ABS32: %x -> %x\n", where, *where);
  68. #endif
  69. break;
  70. case R_ARM_PC24:
  71. case R_ARM_PLT32:
  72. case R_ARM_CALL:
  73. case R_ARM_JUMP24:
  74. addend = *where & 0x00ffffff;
  75. if (addend & 0x00800000)
  76. addend |= 0xff000000;
  77. tmp = sym_val - (Elf32_Addr)where + (addend << 2);
  78. tmp >>= 2;
  79. *where = (*where & 0xff000000) | (tmp & 0x00ffffff);
  80. #ifdef RT_MODULE_DEBUG
  81. rt_kprintf("R_ARM_PC24: %x -> %x\n", where, *where);
  82. #endif
  83. break;
  84. case R_ARM_V4BX:
  85. *where &= 0xf000000f;
  86. *where |= 0x01a0f000;
  87. break;
  88. case R_ARM_GLOB_DAT:
  89. case R_ARM_JUMP_SLOT:
  90. *where = (Elf32_Addr)sym_val;
  91. #ifdef RT_MODULE_DEBUG
  92. rt_kprintf("R_ARM_JUMP_SLOT: 0x%x -> 0x%x 0x%x\n", where, *where, sym_val);
  93. #endif break;
  94. default:
  95. return -1;
  96. }
  97. return 0;
  98. }
  99. static void rt_module_init_object_container(struct rt_module* module)
  100. {
  101. RT_ASSERT(module != RT_NULL);
  102. /* init object container - thread */
  103. rt_list_init(&(module->module_object[RT_Object_Class_Thread].object_list));
  104. module->module_object[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
  105. module->module_object[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
  106. #ifdef RT_USING_SEMAPHORE
  107. /* init object container - semaphore */
  108. rt_list_init(&(module->module_object[RT_Object_Class_Semaphore].object_list));
  109. module->module_object[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
  110. module->module_object[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
  111. #endif
  112. #ifdef RT_USING_MUTEX
  113. /* init object container - mutex */
  114. rt_list_init(&(module->module_object[RT_Object_Class_Mutex].object_list));
  115. module->module_object[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
  116. module->module_object[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
  117. #endif
  118. #ifdef RT_USING_EVENT
  119. /* init object container - event */
  120. rt_list_init(&(module->module_object[RT_Object_Class_Event].object_list));
  121. module->module_object[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
  122. module->module_object[RT_Object_Class_Event].type = RT_Object_Class_Event;
  123. #endif
  124. #ifdef RT_USING_MAILBOX
  125. /* init object container - mailbox */
  126. rt_list_init(&(module->module_object[RT_Object_Class_MailBox].object_list));
  127. module->module_object[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
  128. module->module_object[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
  129. #endif
  130. #ifdef RT_USING_MESSAGEQUEUE
  131. /* init object container - message queue */
  132. rt_list_init(&(module->module_object[RT_Object_Class_MessageQueue].object_list));
  133. module->module_object[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
  134. module->module_object[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
  135. #endif
  136. #ifdef RT_USING_MEMPOOL
  137. /* init object container - memory pool */
  138. rt_list_init(&(module->module_object[RT_Object_Class_MemPool].object_list));
  139. module->module_object[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
  140. module->module_object[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
  141. #endif
  142. #ifdef RT_USING_DEVICE
  143. /* init object container - device */
  144. rt_list_init(&(module->module_object[RT_Object_Class_Device].object_list));
  145. module->module_object[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
  146. module->module_object[RT_Object_Class_Device].type = RT_Object_Class_Device;
  147. #endif
  148. /* init object container - timer */
  149. rt_list_init(&(module->module_object[RT_Object_Class_Timer].object_list));
  150. module->module_object[RT_Object_Class_Timer].object_size = sizeof(struct rt_timer);
  151. module->module_object[RT_Object_Class_Timer].type = RT_Object_Class_Timer;
  152. }
  153. /**
  154. * This function will load a module from memory and create a thread for it
  155. *
  156. * @param name the name of module, which shall be unique
  157. * @param module_ptr the memory address of module image
  158. *
  159. * @return the module object
  160. *
  161. */
  162. rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr)
  163. {
  164. rt_uint32_t index;
  165. rt_uint32_t module_size = 0;
  166. struct rt_module* module = RT_NULL;
  167. rt_uint8_t *ptr, *strtab;
  168. #ifdef RT_MODULE_DEBUG
  169. rt_kprintf("rt_module_load: %s\n", name);
  170. #endif
  171. /* check ELF header */
  172. if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 ||
  173. elf_module->e_ident[EI_CLASS] != ELFCLASS32)
  174. {
  175. rt_kprintf(" module magic error\n");
  176. return RT_NULL;
  177. }
  178. /* get the ELF image size */
  179. for (index = 0; index < elf_module->e_phnum; index++)
  180. {
  181. if(phdr[index].p_type == PT_LOAD)
  182. module_size += phdr[index].p_memsz;
  183. }
  184. if (module_size == 0)
  185. {
  186. rt_kprintf(" module size error\n");
  187. return module;
  188. }
  189. /* allocate module */
  190. module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, (const char*)name);
  191. if (module == RT_NULL) return RT_NULL;
  192. /* allocate module space */
  193. module->module_space = rt_malloc(module_size);
  194. if (module->module_space == RT_NULL)
  195. {
  196. rt_object_delete(&(module->parent));
  197. return RT_NULL;
  198. }
  199. /* zero all space */
  200. ptr = module->module_space;
  201. rt_memset(ptr, 0, module_size);
  202. for (index = 0; index < elf_module->e_phnum; index++)
  203. {
  204. if(phdr[index].p_type == PT_LOAD)
  205. {
  206. rt_memcpy(ptr, (rt_uint8_t*)elf_module + phdr[index].p_offset, phdr[index].p_filesz);
  207. ptr += phdr[index].p_memsz;
  208. }
  209. }
  210. /* set module entry */
  211. module->module_entry = module->module_space + elf_module->e_entry;
  212. /* handle relocation section */
  213. for (index = 0; index < elf_module->e_shnum; index ++)
  214. {
  215. if (IS_REL(shdr[index]))
  216. {
  217. rt_uint32_t i, nr_reloc;
  218. Elf32_Sym *symtab;
  219. Elf32_Rel *rel;
  220. /* get relocate item */
  221. rel = (Elf32_Rel *) ((rt_uint8_t*)module_ptr + shdr[index].sh_offset);
  222. /* locate .rel.plt and .rel.dyn */
  223. symtab =(Elf32_Sym *) ((rt_uint8_t*)module_ptr + shdr[shdr[index].sh_link].sh_offset);
  224. strtab = (rt_uint8_t*) module_ptr + shdr[shdr[shdr[index].sh_link].sh_link].sh_offset;
  225. nr_reloc = (rt_uint32_t) (shdr[index].sh_size / sizeof(Elf32_Rel));
  226. /* relocate every items */
  227. for (i = 0; i < nr_reloc; i ++)
  228. {
  229. Elf32_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)];
  230. #ifdef RT_MODULE_DEBUG
  231. rt_kprintf("relocate symbol %s shndx %d\n", strtab + sym->st_name, sym->st_shndx);
  232. #endif
  233. if(sym->st_shndx != 0)
  234. {
  235. rt_module_arm_relocate(module, rel, (Elf32_Addr)((rt_uint8_t*)module->module_space + sym->st_value));
  236. }
  237. rel ++;
  238. }
  239. }
  240. }
  241. /* init module object container */
  242. rt_module_init_object_container(module);
  243. module->stack_size = 512;
  244. module->thread_priority = 90;
  245. module->module_thread = rt_thread_create(name,
  246. module->module_entry, RT_NULL,
  247. module->stack_size,
  248. module->thread_priority, 10);
  249. module->module_thread->module_parent = module;
  250. rt_thread_startup(module->module_thread);
  251. return module;
  252. }
  253. #ifdef RT_USING_DFS
  254. #include <dfs_posix.h>
  255. /**
  256. * This function will load a module from file
  257. *
  258. * @param name the name of module, which shall be unique
  259. * @param filename the file name of application module image
  260. *
  261. * @return the module object
  262. *
  263. */
  264. rt_module_t rt_module_load_from_file(const rt_uint8_t* name, const char* filename)
  265. {
  266. int fd, length;
  267. struct rt_module* module;
  268. struct _stat s;
  269. char *buffer;
  270. stat(filename, &s);
  271. buffer = (char *)rt_malloc(s.st_size);
  272. fd = open(filename, O_RDONLY, 0);
  273. length = read(fd, buffer, s.st_size);
  274. if (length <= 0)
  275. {
  276. rt_kprintf("check: read file failed\n");
  277. close(fd);
  278. rt_free(buffer);
  279. return RT_NULL;
  280. }
  281. rt_kprintf("read %d bytes from file\n", length);
  282. module = rt_module_load(name, (void *)buffer);
  283. rt_free(buffer);
  284. close(fd);
  285. return module;
  286. }
  287. #endif
  288. /**
  289. * This function will unload a module from memory and release resources
  290. *
  291. * @param module the module to be unloaded
  292. *
  293. * @return the operation status, RT_EOK on OK; -RT_ERROR on error
  294. *
  295. */
  296. rt_err_t rt_module_unload(rt_module_t module)
  297. {
  298. int i;
  299. struct rt_object* object;
  300. struct rt_list_node *list, *node;
  301. #ifdef RT_MODULE_DEBUG
  302. rt_kprintf("rt_module_unload %s\n", module->parent.name);
  303. #endif
  304. /* check parameter */
  305. RT_ASSERT(module != RT_NULL);
  306. /* suspend module main thread */
  307. if (module->module_thread->stat == RT_THREAD_READY)
  308. rt_thread_suspend(module->module_thread);
  309. /* delete all module object */
  310. for(i = RT_Object_Class_Thread; i < RT_Object_Class_Module; i++)
  311. {
  312. list = &module->module_object[i].object_list;
  313. for (node = list->next; node != list; node = node->next)
  314. {
  315. object = rt_list_entry(node, struct rt_object, list);
  316. if (rt_object_is_systemobject(object) == RT_EOK)
  317. {
  318. /* detach static objcet */
  319. rt_object_detach(object);
  320. }
  321. else
  322. {
  323. /* delete dynamic object */
  324. rt_object_delete(object);
  325. }
  326. }
  327. }
  328. /* release module memory */
  329. rt_free(module->module_space);
  330. rt_object_delete((struct rt_object *)module);
  331. return RT_EOK;
  332. }
  333. /**
  334. * This function will find the specified module.
  335. *
  336. * @param name the name of module finding
  337. *
  338. * @return the module
  339. */
  340. rt_module_t rt_module_find(char* name)
  341. {
  342. struct rt_object_information *information;
  343. struct rt_object* object;
  344. struct rt_list_node* node;
  345. extern struct rt_object_information rt_object_container[];
  346. /* enter critical */
  347. rt_enter_critical();
  348. /* try to find device object */
  349. information = &rt_object_container[RT_Object_Class_Thread];
  350. for (node = information->object_list.next; node != &(information->object_list); node = node->next)
  351. {
  352. object = rt_list_entry(node, struct rt_object, list);
  353. if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
  354. {
  355. /* leave critical */
  356. rt_exit_critical();
  357. return (rt_module_t)object;
  358. }
  359. }
  360. /* leave critical */
  361. rt_exit_critical();
  362. /* not found */
  363. return RT_NULL;
  364. }
  365. #if defined(RT_USING_FINSH)
  366. #include <finsh.h>
  367. FINSH_FUNCTION_EXPORT(rt_module_load_from_file, load module from file);
  368. #endif
  369. #endif