module.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  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 <rtm.h>
  16. #include <rtthread.h>
  17. #include "module.h"
  18. #include "kservice.h"
  19. #define RT_MODULE_DEBUG
  20. #ifdef RT_USING_MODULE
  21. #define elf_module ((Elf32_Ehdr *)module_ptr)
  22. #define shdr ((Elf32_Shdr *)((rt_uint8_t *)module_ptr + elf_module->e_shoff))
  23. #define IS_PROG(s) (s.sh_type == SHT_PROGBITS)
  24. #define IS_NOPROG(s) (s.sh_type == SHT_NOBITS)
  25. #define IS_REL(s) (s.sh_type == SHT_REL)
  26. #define IS_RELA(s) (s.sh_type == SHT_RELA)
  27. #define IS_ALLOC(s) (s.sh_flags == SHF_ALLOC)
  28. #define IS_AX(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_EXECINSTR))
  29. #define IS_AW(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_WRITE))
  30. rt_list_t rt_module_symbol_list;
  31. struct rt_module* rt_current_module;
  32. struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL, *_rt_module_symtab_end = RT_NULL;
  33. extern const struct rt_shell ishell;
  34. void rt_system_module_init()
  35. {
  36. #ifdef __CC_ARM
  37. extern int RTMSymTab$$Base;
  38. extern int RTMSymTab$$Limit;
  39. _rt_module_symtab_begin = (struct rt_module_symtab *)&RTMSymTab$$Base;
  40. _rt_module_symtab_end = (struct rt_module_symtab *)&RTMSymTab$$Limit;
  41. #elif defined(__GNUC__)
  42. extern int __rtmsymtab_start;
  43. extern int __rtmsymtab_end;
  44. _rt_module_symtab_begin = (struct rt_module_symtab *)&__rtmsymtab_start;
  45. _rt_module_symtab_end = (struct rt_module_symtab *)&__rtmsymtab_end;
  46. #endif
  47. rt_list_init(&rt_module_symbol_list);
  48. }
  49. rt_uint32_t rt_module_symbol_find(const rt_uint8_t* sym_str)
  50. {
  51. /* find in kernel symbol table */
  52. struct rt_module_symtab* index;
  53. for (index = _rt_module_symtab_begin; index != _rt_module_symtab_end; index ++)
  54. {
  55. if (strcmp(index->name, (const char*)sym_str) == 0)
  56. return index->addr;
  57. }
  58. return 0;
  59. }
  60. int rt_module_arm_relocate(struct rt_module* module, Elf32_Rel *rel, Elf32_Addr sym_val, rt_uint32_t module_addr)
  61. {
  62. Elf32_Addr *where, tmp;
  63. Elf32_Sword addend;
  64. where = (Elf32_Addr *)((rt_uint8_t*)module->module_space + rel->r_offset - module_addr);
  65. switch (ELF32_R_TYPE(rel->r_info))
  66. {
  67. case R_ARM_NONE:
  68. break;
  69. case R_ARM_ABS32:
  70. *where += (Elf32_Addr)sym_val;
  71. #ifdef RT_MODULE_DEBUG
  72. rt_kprintf("R_ARM_ABS32: %x -> %x\n", where, *where);
  73. #endif
  74. break;
  75. case R_ARM_PC24:
  76. case R_ARM_PLT32:
  77. case R_ARM_CALL:
  78. case R_ARM_JUMP24:
  79. addend = *where & 0x00ffffff;
  80. if (addend & 0x00800000)
  81. addend |= 0xff000000;
  82. tmp = sym_val - (Elf32_Addr)where + (addend << 2);
  83. tmp >>= 2;
  84. *where = (*where & 0xff000000) | (tmp & 0x00ffffff);
  85. #ifdef RT_MODULE_DEBUG
  86. rt_kprintf("R_ARM_PC24: %x -> %x\n", where, *where);
  87. #endif
  88. break;
  89. case R_ARM_V4BX:
  90. *where &= 0xf000000f;
  91. *where |= 0x01a0f000;
  92. break;
  93. default:
  94. return -1;
  95. }
  96. return 0;
  97. }
  98. static void rt_module_init_object_container(struct rt_module* module)
  99. {
  100. RT_ASSERT(module != RT_NULL);
  101. /* init object container - thread */
  102. rt_list_init(&(module->module_object[RT_Object_Class_Thread].object_list));
  103. module->module_object[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
  104. module->module_object[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
  105. #ifdef RT_USING_SEMAPHORE
  106. /* init object container - semaphore */
  107. rt_list_init(&(module->module_object[RT_Object_Class_Semaphore].object_list));
  108. module->module_object[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
  109. module->module_object[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
  110. #endif
  111. #ifdef RT_USING_MUTEX
  112. /* init object container - mutex */
  113. rt_list_init(&(module->module_object[RT_Object_Class_Mutex].object_list));
  114. module->module_object[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
  115. module->module_object[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
  116. #endif
  117. #ifdef RT_USING_EVENT
  118. /* init object container - event */
  119. rt_list_init(&(module->module_object[RT_Object_Class_Event].object_list));
  120. module->module_object[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
  121. module->module_object[RT_Object_Class_Event].type = RT_Object_Class_Event;
  122. #endif
  123. #ifdef RT_USING_MAILBOX
  124. /* init object container - mailbox */
  125. rt_list_init(&(module->module_object[RT_Object_Class_MailBox].object_list));
  126. module->module_object[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
  127. module->module_object[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
  128. #endif
  129. #ifdef RT_USING_MESSAGEQUEUE
  130. /* init object container - message queue */
  131. rt_list_init(&(module->module_object[RT_Object_Class_MessageQueue].object_list));
  132. module->module_object[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
  133. module->module_object[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
  134. #endif
  135. #ifdef RT_USING_MEMPOOL
  136. /* init object container - memory pool */
  137. rt_list_init(&(module->module_object[RT_Object_Class_MemPool].object_list));
  138. module->module_object[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
  139. module->module_object[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
  140. #endif
  141. #ifdef RT_USING_DEVICE
  142. /* init object container - device */
  143. rt_list_init(&(module->module_object[RT_Object_Class_Device].object_list));
  144. module->module_object[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
  145. module->module_object[RT_Object_Class_Device].type = RT_Object_Class_Device;
  146. #endif
  147. /* init object container - timer */
  148. rt_list_init(&(module->module_object[RT_Object_Class_Timer].object_list));
  149. module->module_object[RT_Object_Class_Timer].object_size = sizeof(struct rt_timer);
  150. module->module_object[RT_Object_Class_Timer].type = RT_Object_Class_Timer;
  151. }
  152. struct rt_module* rt_module_load(void* module_ptr, const rt_uint8_t* name)
  153. {
  154. rt_uint32_t index, rodata_addr = 0, data_addr = 0, bss_addr = 0;
  155. rt_uint32_t module_addr = 0, module_size = 0;
  156. struct rt_module* module = RT_NULL;
  157. rt_uint8_t *ptr, *strtab, *shstrab;
  158. #ifdef RT_MODULE_DEBUG
  159. rt_kprintf("rt_module_load: %s\n", name);
  160. #endif
  161. /* check ELF header */
  162. if (rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0 ||
  163. elf_module->e_ident[EI_CLASS] != ELFCLASS32)
  164. return RT_NULL;
  165. /* get the ELF image size */
  166. for (index = 0; index < elf_module->e_shnum; index++)
  167. {
  168. /* text */
  169. if (IS_PROG(shdr[index]) && IS_AX(shdr[index]))
  170. {
  171. module_size += shdr[index].sh_size;
  172. module_addr = shdr[index].sh_addr;
  173. }
  174. /* rodata */
  175. if (IS_PROG(shdr[index]) && IS_ALLOC(shdr[index]))
  176. {
  177. module_size += shdr[index].sh_size;
  178. }
  179. /* data */
  180. if (IS_PROG(shdr[index]) && IS_AW(shdr[index]))
  181. {
  182. module_size += shdr[index].sh_size;
  183. }
  184. /* bss */
  185. if (IS_NOPROG(shdr[index]) && IS_AW(shdr[index]))
  186. {
  187. module_size += shdr[index].sh_size;
  188. }
  189. }
  190. /* no text, data and bss on image */
  191. if (module_size == 0) return module;
  192. /* allocate module */
  193. module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, (const char*)name);
  194. if (module == RT_NULL) return RT_NULL;
  195. /* allocate module space */
  196. module->module_space = rt_malloc(module_size);
  197. if (module->module_space == RT_NULL)
  198. {
  199. rt_object_delete(&(module->parent));
  200. return RT_NULL;
  201. }
  202. /* zero all space */
  203. ptr = module->module_space;
  204. rt_memset(ptr, 0, module_size);
  205. /* load text and data section */
  206. for (index = 0; index < elf_module->e_shnum; index++)
  207. {
  208. /* load text section */
  209. if (IS_PROG(shdr[index]) && IS_AX(shdr[index]))
  210. {
  211. rt_memcpy(ptr, (rt_uint8_t*)elf_module + shdr[index].sh_offset, shdr[index].sh_size);
  212. ptr += shdr[index].sh_size;
  213. }
  214. /* load rodata section */
  215. if (IS_PROG(shdr[index]) && IS_ALLOC(shdr[index]))
  216. {
  217. rt_memcpy(ptr, (rt_uint8_t*)elf_module + shdr[index].sh_offset, shdr[index].sh_size);
  218. rodata_addr = (rt_uint32_t)ptr;
  219. ptr += shdr[index].sh_size;
  220. }
  221. /* load data section */
  222. if (IS_PROG(shdr[index]) && IS_AW(shdr[index]))
  223. {
  224. data_addr = (rt_uint32_t)ptr;
  225. rt_kprintf("data section address 0x%x\n", data_addr);
  226. rt_memcpy(ptr, (rt_uint8_t*)elf_module + shdr[index].sh_offset, shdr[index].sh_size);
  227. ptr += shdr[index].sh_size;
  228. }
  229. /* load bss section */
  230. if (IS_NOPROG(shdr[index]) && IS_AW(shdr[index]))
  231. {
  232. bss_addr = (rt_uint32_t)ptr;
  233. rt_kprintf("bss section address 0x%x\n", bss_addr);
  234. rt_memset(ptr, 0, shdr[index].sh_size);
  235. }
  236. }
  237. /* set module entry */
  238. module->module_entry = (rt_uint8_t*)module->module_space + elf_module->e_entry - module_addr;
  239. /* handle relocation section */
  240. for (index = 0; index < elf_module->e_shnum; index ++)
  241. {
  242. if (IS_REL(shdr[index]))
  243. {
  244. rt_uint32_t i, nr_reloc;
  245. Elf32_Sym *symtab;
  246. Elf32_Rel *rel;
  247. /* get relocate item */
  248. rel = (Elf32_Rel *) ((rt_uint8_t*)module_ptr + shdr[index].sh_offset);
  249. /* locate .dynsym and .dynstr */
  250. symtab =(Elf32_Sym *) ((rt_uint8_t*)module_ptr + shdr[shdr[index].sh_link].sh_offset);
  251. strtab = (rt_uint8_t*) module_ptr + shdr[shdr[shdr[index].sh_link].sh_link].sh_offset;
  252. shstrab = (rt_uint8_t*) module_ptr + shdr[elf_module->e_shstrndx].sh_offset;
  253. nr_reloc = (rt_uint32_t) (shdr[index].sh_size / sizeof(Elf32_Rel));
  254. /* relocate every items */
  255. for (i = 0; i < nr_reloc; i ++)
  256. {
  257. Elf32_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)];
  258. #ifdef RT_MODULE_DEBUG
  259. rt_kprintf("relocate symbol %s\n", strtab + sym->st_name);
  260. #endif
  261. if (sym->st_shndx != STN_UNDEF)
  262. {
  263. if((ELF_ST_TYPE(sym->st_info) == STT_SECTION)
  264. || (ELF_ST_TYPE(sym->st_info) == STT_OBJECT))
  265. {
  266. rt_kprintf("section name %s\n", shstrab + shdr[sym->st_shndx].sh_name);
  267. if (rt_strncmp(shstrab + shdr[sym->st_shndx].sh_name, ELF_RODATA, 8) == 0)
  268. {
  269. /* relocate rodata section */
  270. rt_module_arm_relocate(module, rel,
  271. (Elf32_Addr)(rodata_addr + sym->st_value),
  272. module_addr);
  273. }
  274. else if(strncmp(shstrab + shdr[sym->st_shndx].sh_name, ELF_BSS, 5) == 0)
  275. {
  276. /* relocate bss section */
  277. rt_module_arm_relocate(module, rel,
  278. (Elf32_Addr)bss_addr + sym->st_value,
  279. module_addr);
  280. }
  281. else if(strncmp(shstrab + shdr[sym->st_shndx].sh_name, ELF_DATA, 6) == 0)
  282. {
  283. /* relocate bss section */
  284. rt_module_arm_relocate(module, rel,
  285. (Elf32_Addr)data_addr + sym->st_value,
  286. module_addr);
  287. }
  288. }
  289. else if(ELF_ST_TYPE(sym->st_info) == STT_FUNC )
  290. {
  291. /* relocate function */
  292. rt_module_arm_relocate(module, rel,
  293. (Elf32_Addr)((rt_uint8_t*)module->module_space - module_addr + sym->st_value),
  294. module_addr);
  295. }
  296. }
  297. else
  298. {
  299. Elf32_Addr addr;
  300. if(ELF32_R_TYPE(rel->r_info) != R_ARM_V4BX)
  301. {
  302. #ifdef RT_MODULE_DEBUG
  303. rt_kprintf("unresolved relocate symbol: %s\n", strtab + sym->st_name);
  304. #endif
  305. /* need to resolve symbol in kernel symbol table */
  306. addr = rt_module_symbol_find(strtab + sym->st_name);
  307. if (addr != (Elf32_Addr)RT_NULL)
  308. rt_module_arm_relocate(module, rel, addr, module_addr);
  309. else rt_kprintf("can't find %s in kernel symbol table\n", strtab + sym->st_name);
  310. }
  311. else
  312. {
  313. rt_module_arm_relocate(module, rel, addr, module_addr);
  314. }
  315. }
  316. rel ++;
  317. }
  318. }
  319. }
  320. /* init module object container */
  321. rt_module_init_object_container(module);
  322. /* enter elf entry */
  323. ((elf_entry)module->module_entry)(&ishell, &module->module_info);
  324. return module;
  325. }
  326. void rt_module_run(struct rt_module* module)
  327. {
  328. struct rt_module_info *info;
  329. /* check parameter */
  330. RT_ASSERT(module != RT_NULL);
  331. RT_ASSERT(module->module_info != RT_NULL);
  332. info = module->module_info;
  333. if(info->module_type == RT_Module_Class_APP)
  334. {
  335. /* application */
  336. module->module_thread = rt_thread_create(module->parent.name,
  337. module->module_entry, RT_NULL,
  338. 512, 90, 10);
  339. module->module_thread->module_parent = module;
  340. rt_thread_startup(module->module_thread);
  341. }
  342. else if(info->module_type == RT_Module_Class_EXTENSION)
  343. {
  344. /* extension */
  345. }
  346. else if(info->module_type == RT_Module_Class_SERVICE)
  347. {
  348. /* service */
  349. }
  350. }
  351. void rt_module_unload(struct rt_module* module)
  352. {
  353. int i;
  354. struct rt_object* object;
  355. struct rt_timer *timer;
  356. struct rt_list_node *list, *node;
  357. /* check parameter */
  358. RT_ASSERT(module != RT_NULL);
  359. /* suspend module main thread */
  360. if (module->module_thread->stat == RT_THREAD_READY)
  361. rt_thread_suspend(module->module_thread);
  362. /* delete all module object */
  363. for(i = RT_Object_Class_Thread; i < RT_Object_Class_Module; i++)
  364. {
  365. list = &module->module_object[i].object_list;
  366. for (node = list->next; node != list; node = node->next)
  367. {
  368. object = rt_list_entry(node, struct rt_object, list);
  369. if (rt_object_is_systemobject(object) == RT_EOK)
  370. {
  371. /* detach static objcet */
  372. rt_object_detach(object);
  373. }
  374. else
  375. {
  376. /* delete dynamic object */
  377. rt_object_delete(object);
  378. }
  379. }
  380. }
  381. /* release module memory */
  382. rt_free(module->module_space);
  383. rt_object_delete((struct rt_object *)module);
  384. }
  385. rt_module_t rt_module_find(char* name)
  386. {
  387. struct rt_object_information *information;
  388. struct rt_object* object;
  389. struct rt_list_node* node;
  390. extern struct rt_object_information rt_object_container[];
  391. /* enter critical */
  392. rt_enter_critical();
  393. /* try to find device object */
  394. information = &rt_object_container[RT_Object_Class_Thread];
  395. for (node = information->object_list.next; node != &(information->object_list); node = node->next)
  396. {
  397. object = rt_list_entry(node, struct rt_object, list);
  398. if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
  399. {
  400. /* leave critical */
  401. rt_exit_critical();
  402. return (rt_module_t)object;
  403. }
  404. }
  405. /* leave critical */
  406. rt_exit_critical();
  407. /* not found */
  408. return RT_NULL;
  409. }
  410. #endif