module.c 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733
  1. /*
  2. * File : module.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2010-01-09 Bernard first version
  23. * 2010-04-09 yi.qiu implement based on first version
  24. * 2010-10-23 yi.qiu implement module memory allocator
  25. * 2011-05-25 yi.qiu implement module hook function
  26. * 2011-06-23 yi.qiu rewrite module memory allocator
  27. * 2012-11-23 Bernard using RT_DEBUG_LOG instead of rt_kprintf.
  28. * 2012-11-28 Bernard remove rt_current_module and user
  29. * can use rt_module_unload to remove a module.
  30. */
  31. #include <rthw.h>
  32. #include <rtthread.h>
  33. #include <rtm.h>
  34. #ifdef RT_USING_MODULE
  35. #include "module.h"
  36. #define elf_module ((Elf32_Ehdr *)module_ptr)
  37. #define shdr ((Elf32_Shdr *)((rt_uint8_t *)module_ptr + elf_module->e_shoff))
  38. #define phdr ((Elf32_Phdr *)((rt_uint8_t *)module_ptr + elf_module->e_phoff))
  39. #define IS_PROG(s) (s.sh_type == SHT_PROGBITS)
  40. #define IS_NOPROG(s) (s.sh_type == SHT_NOBITS)
  41. #define IS_REL(s) (s.sh_type == SHT_REL)
  42. #define IS_RELA(s) (s.sh_type == SHT_RELA)
  43. #define IS_ALLOC(s) (s.sh_flags == SHF_ALLOC)
  44. #define IS_AX(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_EXECINSTR))
  45. #define IS_AW(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_WRITE))
  46. #ifdef RT_USING_SLAB
  47. #define PAGE_COUNT_MAX 256
  48. /* module memory allocator */
  49. struct rt_mem_head
  50. {
  51. rt_size_t size; /* size of memory block */
  52. struct rt_mem_head *next; /* next valid memory block */
  53. };
  54. struct rt_page_info
  55. {
  56. rt_uint32_t *page_ptr;
  57. rt_uint32_t npage;
  58. };
  59. static void *rt_module_malloc_page(rt_size_t npages);
  60. static void rt_module_free_page(rt_module_t module,
  61. void *page_ptr,
  62. rt_size_t npages);
  63. static struct rt_semaphore mod_sem;
  64. #endif
  65. static struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL;
  66. static struct rt_module_symtab *_rt_module_symtab_end = RT_NULL;
  67. /**
  68. * @ingroup SystemInit
  69. *
  70. * This function will initialize system module
  71. */
  72. void rt_system_module_init(void)
  73. {
  74. #ifdef __GNUC__
  75. extern int __rtmsymtab_start;
  76. extern int __rtmsymtab_end;
  77. _rt_module_symtab_begin = (struct rt_module_symtab *)&__rtmsymtab_start;
  78. _rt_module_symtab_end = (struct rt_module_symtab *)&__rtmsymtab_end;
  79. #elif defined (__CC_ARM)
  80. extern int RTMSymTab$$Base;
  81. extern int RTMSymTab$$Limit;
  82. _rt_module_symtab_begin = (struct rt_module_symtab *)&RTMSymTab$$Base;
  83. _rt_module_symtab_end = (struct rt_module_symtab *)&RTMSymTab$$Limit;
  84. #endif
  85. #ifdef RT_USING_SLAB
  86. /* initialize heap semaphore */
  87. rt_sem_init(&mod_sem, "module", 1, RT_IPC_FLAG_FIFO);
  88. #endif
  89. }
  90. INIT_COMPONENT_EXPORT(rt_system_module_init);
  91. static rt_uint32_t rt_module_symbol_find(const char *sym_str)
  92. {
  93. /* find in kernel symbol table */
  94. struct rt_module_symtab *index;
  95. for (index = _rt_module_symtab_begin;
  96. index != _rt_module_symtab_end;
  97. index ++)
  98. {
  99. if (rt_strcmp(index->name, sym_str) == 0)
  100. return (rt_uint32_t)index->addr;
  101. }
  102. return 0;
  103. }
  104. /**
  105. * This function will return self module object
  106. *
  107. * @return the self module object
  108. */
  109. rt_module_t rt_module_self(void)
  110. {
  111. rt_thread_t tid;
  112. tid = rt_thread_self();
  113. if (tid == RT_NULL)
  114. return RT_NULL;
  115. /* return current module */
  116. return (rt_module_t)tid->module_id;
  117. }
  118. static int rt_module_arm_relocate(struct rt_module *module,
  119. Elf32_Rel *rel,
  120. Elf32_Addr sym_val)
  121. {
  122. Elf32_Addr *where, tmp;
  123. Elf32_Sword addend, offset;
  124. rt_uint32_t upper, lower, sign, j1, j2;
  125. where = (Elf32_Addr *)((rt_uint8_t *)module->module_space + rel->r_offset);
  126. switch (ELF32_R_TYPE(rel->r_info))
  127. {
  128. case R_ARM_NONE:
  129. break;
  130. case R_ARM_ABS32:
  131. *where += (Elf32_Addr)sym_val;
  132. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_ABS32: %x -> %x\n",
  133. where, *where));
  134. break;
  135. case R_ARM_PC24:
  136. case R_ARM_PLT32:
  137. case R_ARM_CALL:
  138. case R_ARM_JUMP24:
  139. addend = *where & 0x00ffffff;
  140. if (addend & 0x00800000)
  141. addend |= 0xff000000;
  142. tmp = sym_val - (Elf32_Addr)where + (addend << 2);
  143. tmp >>= 2;
  144. *where = (*where & 0xff000000) | (tmp & 0x00ffffff);
  145. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_PC24: %x -> %x\n",
  146. where, *where));
  147. break;
  148. case R_ARM_REL32:
  149. *where += sym_val - (Elf32_Addr)where;
  150. RT_DEBUG_LOG(RT_DEBUG_MODULE,
  151. ("R_ARM_REL32: %x -> %x, sym %x, offset %x\n",
  152. where, *where, sym_val, rel->r_offset));
  153. break;
  154. case R_ARM_V4BX:
  155. *where &= 0xf000000f;
  156. *where |= 0x01a0f000;
  157. break;
  158. case R_ARM_GLOB_DAT:
  159. case R_ARM_JUMP_SLOT:
  160. *where = (Elf32_Addr)sym_val;
  161. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_JUMP_SLOT: 0x%x -> 0x%x 0x%x\n",
  162. where, *where, sym_val));
  163. break;
  164. #if 0 /* To do */
  165. case R_ARM_GOT_BREL:
  166. temp = (Elf32_Addr)sym_val;
  167. *where = (Elf32_Addr)&temp;
  168. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_GOT_BREL: 0x%x -> 0x%x 0x%x\n",
  169. where, *where, sym_val));
  170. break;
  171. #endif
  172. case R_ARM_RELATIVE:
  173. *where = (Elf32_Addr)sym_val + *where;
  174. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_RELATIVE: 0x%x -> 0x%x 0x%x\n",
  175. where, *where, sym_val));
  176. break;
  177. case R_ARM_THM_CALL:
  178. case R_ARM_THM_JUMP24:
  179. upper = *(rt_uint16_t *)where;
  180. lower = *(rt_uint16_t *)((Elf32_Addr)where + 2);
  181. sign = (upper >> 10) & 1;
  182. j1 = (lower >> 13) & 1;
  183. j2 = (lower >> 11) & 1;
  184. offset = (sign << 24) |
  185. ((~(j1 ^ sign) & 1) << 23) |
  186. ((~(j2 ^ sign) & 1) << 22) |
  187. ((upper & 0x03ff) << 12) |
  188. ((lower & 0x07ff) << 1);
  189. if (offset & 0x01000000)
  190. offset -= 0x02000000;
  191. offset += sym_val - (Elf32_Addr)where;
  192. if (!(offset & 1) ||
  193. offset <= (rt_int32_t)0xff000000 ||
  194. offset >= (rt_int32_t)0x01000000)
  195. {
  196. rt_kprintf("Module: Only Thumb addresses allowed\n");
  197. return -1;
  198. }
  199. sign = (offset >> 24) & 1;
  200. j1 = sign ^ (~(offset >> 23) & 1);
  201. j2 = sign ^ (~(offset >> 22) & 1);
  202. *(rt_uint16_t *)where = (rt_uint16_t)((upper & 0xf800) |
  203. (sign << 10) |
  204. ((offset >> 12) & 0x03ff));
  205. *(rt_uint16_t *)(where + 2) = (rt_uint16_t)((lower & 0xd000) |
  206. (j1 << 13) | (j2 << 11) |
  207. ((offset >> 1) & 0x07ff));
  208. upper = *(rt_uint16_t *)where;
  209. lower = *(rt_uint16_t *)((Elf32_Addr)where + 2);
  210. break;
  211. default:
  212. return -1;
  213. }
  214. return 0;
  215. }
  216. static void rt_module_init_object_container(struct rt_module *module)
  217. {
  218. RT_ASSERT(module != RT_NULL);
  219. /* initialize object container - thread */
  220. rt_list_init(&(module->module_object[RT_Object_Class_Thread].object_list));
  221. module->module_object[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
  222. module->module_object[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
  223. #ifdef RT_USING_SEMAPHORE
  224. /* initialize object container - semaphore */
  225. rt_list_init(&(module->module_object[RT_Object_Class_Semaphore].object_list));
  226. module->module_object[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
  227. module->module_object[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
  228. #endif
  229. #ifdef RT_USING_MUTEX
  230. /* initialize object container - mutex */
  231. rt_list_init(&(module->module_object[RT_Object_Class_Mutex].object_list));
  232. module->module_object[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
  233. module->module_object[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
  234. #endif
  235. #ifdef RT_USING_EVENT
  236. /* initialize object container - event */
  237. rt_list_init(&(module->module_object[RT_Object_Class_Event].object_list));
  238. module->module_object[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
  239. module->module_object[RT_Object_Class_Event].type = RT_Object_Class_Event;
  240. #endif
  241. #ifdef RT_USING_MAILBOX
  242. /* initialize object container - mailbox */
  243. rt_list_init(&(module->module_object[RT_Object_Class_MailBox].object_list));
  244. module->module_object[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
  245. module->module_object[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
  246. #endif
  247. #ifdef RT_USING_MESSAGEQUEUE
  248. /* initialize object container - message queue */
  249. rt_list_init(&(module->module_object[RT_Object_Class_MessageQueue].object_list));
  250. module->module_object[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
  251. module->module_object[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
  252. #endif
  253. #ifdef RT_USING_MEMHEAP
  254. /* initialize object container - memory heap */
  255. rt_list_init(&(module->module_object[RT_Object_Class_MemHeap].object_list));
  256. module->module_object[RT_Object_Class_MemHeap].object_size = sizeof(struct rt_memheap);
  257. module->module_object[RT_Object_Class_MemHeap].type = RT_Object_Class_MemHeap;
  258. #endif
  259. #ifdef RT_USING_MEMPOOL
  260. /* initialize object container - memory pool */
  261. rt_list_init(&(module->module_object[RT_Object_Class_MemPool].object_list));
  262. module->module_object[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
  263. module->module_object[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
  264. #endif
  265. #ifdef RT_USING_DEVICE
  266. /* initialize object container - device */
  267. rt_list_init(&(module->module_object[RT_Object_Class_Device].object_list));
  268. module->module_object[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
  269. module->module_object[RT_Object_Class_Device].type = RT_Object_Class_Device;
  270. #endif
  271. /* initialize object container - timer */
  272. rt_list_init(&(module->module_object[RT_Object_Class_Timer].object_list));
  273. module->module_object[RT_Object_Class_Timer].object_size = sizeof(struct rt_timer);
  274. module->module_object[RT_Object_Class_Timer].type = RT_Object_Class_Timer;
  275. }
  276. #ifdef RT_USING_HOOK
  277. static void (*rt_module_load_hook)(rt_module_t module);
  278. static void (*rt_module_unload_hook)(rt_module_t module);
  279. /**
  280. * @addtogroup Hook
  281. */
  282. /*@{*/
  283. /**
  284. * This function will set a hook function, which will be invoked when module
  285. * be loaded to system.
  286. *
  287. * @param hook the hook function
  288. */
  289. void rt_module_load_sethook(void (*hook)(rt_module_t module))
  290. {
  291. rt_module_load_hook = hook;
  292. }
  293. /**
  294. * This function will set a hook function, which will be invoked when module
  295. * be unloaded from system.
  296. *
  297. * @param hook the hook function
  298. */
  299. void rt_module_unload_sethook(void (*hook)(rt_module_t module))
  300. {
  301. rt_module_unload_hook = hook;
  302. }
  303. /*@}*/
  304. #endif
  305. static struct rt_module *_load_shared_object(const char *name,
  306. void *module_ptr)
  307. {
  308. rt_uint8_t *ptr = RT_NULL;
  309. rt_module_t module = RT_NULL;
  310. rt_bool_t linked = RT_FALSE;
  311. rt_uint32_t index, module_size = 0;
  312. RT_ASSERT(module_ptr != RT_NULL);
  313. if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) == 0)
  314. {
  315. /* rtmlinker finished */
  316. linked = RT_TRUE;
  317. }
  318. /* get the ELF image size */
  319. for (index = 0; index < elf_module->e_phnum; index++)
  320. {
  321. if (phdr[index].p_type == PT_LOAD)
  322. module_size += phdr[index].p_memsz;
  323. }
  324. if (module_size == 0)
  325. {
  326. rt_kprintf("Module: size error\n");
  327. return RT_NULL;
  328. }
  329. /* allocate module */
  330. module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module,
  331. name);
  332. if (!module)
  333. return RT_NULL;
  334. module->nref = 0;
  335. /* allocate module space */
  336. module->module_space = rt_malloc(module_size);
  337. if (module->module_space == RT_NULL)
  338. {
  339. rt_kprintf("Module: allocate space failed.\n");
  340. rt_object_delete(&(module->parent));
  341. return RT_NULL;
  342. }
  343. /* zero all space */
  344. ptr = module->module_space;
  345. rt_memset(ptr, 0, module_size);
  346. for (index = 0; index < elf_module->e_phnum; index++)
  347. {
  348. if (phdr[index].p_type == PT_LOAD)
  349. {
  350. rt_memcpy(ptr + phdr[index].p_paddr,
  351. (rt_uint8_t *)elf_module + phdr[index].p_offset,
  352. phdr[index].p_filesz);
  353. }
  354. }
  355. /* set module entry */
  356. module->module_entry = module->module_space + elf_module->e_entry;
  357. /* handle relocation section */
  358. for (index = 0; index < elf_module->e_shnum; index ++)
  359. {
  360. rt_uint32_t i, nr_reloc;
  361. Elf32_Sym *symtab;
  362. Elf32_Rel *rel;
  363. rt_uint8_t *strtab;
  364. static rt_bool_t unsolved = RT_FALSE;
  365. if (!IS_REL(shdr[index]))
  366. continue;
  367. /* get relocate item */
  368. rel = (Elf32_Rel *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset);
  369. /* locate .rel.plt and .rel.dyn section */
  370. symtab = (Elf32_Sym *)((rt_uint8_t *)module_ptr +
  371. shdr[shdr[index].sh_link].sh_offset);
  372. strtab = (rt_uint8_t *)module_ptr +
  373. shdr[shdr[shdr[index].sh_link].sh_link].sh_offset;
  374. nr_reloc = (rt_uint32_t)(shdr[index].sh_size / sizeof(Elf32_Rel));
  375. /* relocate every items */
  376. for (i = 0; i < nr_reloc; i ++)
  377. {
  378. Elf32_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)];
  379. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("relocate symbol %s shndx %d\n",
  380. strtab + sym->st_name,
  381. sym->st_shndx));
  382. if ((sym->st_shndx != SHT_NULL) ||
  383. (ELF_ST_BIND(sym->st_info) == STB_LOCAL))
  384. {
  385. rt_module_arm_relocate(module, rel,
  386. (Elf32_Addr)(module->module_space + sym->st_value));
  387. }
  388. else if (!linked)
  389. {
  390. Elf32_Addr addr;
  391. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("relocate symbol: %s\n",
  392. strtab + sym->st_name));
  393. /* need to resolve symbol in kernel symbol table */
  394. addr = rt_module_symbol_find((const char *)(strtab + sym->st_name));
  395. if (addr == 0)
  396. {
  397. rt_kprintf("Module: can't find %s in kernel symbol table\n",
  398. strtab + sym->st_name);
  399. unsolved = RT_TRUE;
  400. }
  401. else
  402. rt_module_arm_relocate(module, rel, addr);
  403. }
  404. rel ++;
  405. }
  406. if (unsolved)
  407. {
  408. rt_object_delete(&(module->parent));
  409. return RT_NULL;
  410. }
  411. }
  412. /* construct module symbol table */
  413. for (index = 0; index < elf_module->e_shnum; index ++)
  414. {
  415. /* find .dynsym section */
  416. rt_uint8_t *shstrab;
  417. shstrab = (rt_uint8_t *)module_ptr +
  418. shdr[elf_module->e_shstrndx].sh_offset;
  419. if (rt_strcmp((const char *)(shstrab + shdr[index].sh_name), ELF_DYNSYM) == 0)
  420. break;
  421. }
  422. /* found .dynsym section */
  423. if (index != elf_module->e_shnum)
  424. {
  425. int i, count = 0;
  426. Elf32_Sym *symtab = RT_NULL;
  427. rt_uint8_t *strtab = RT_NULL;
  428. symtab =(Elf32_Sym *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset);
  429. strtab = (rt_uint8_t *)module_ptr + shdr[shdr[index].sh_link].sh_offset;
  430. for (i=0; i<shdr[index].sh_size/sizeof(Elf32_Sym); i++)
  431. {
  432. if ((ELF_ST_BIND(symtab[i].st_info) == STB_GLOBAL) &&
  433. (ELF_ST_TYPE(symtab[i].st_info) == STT_FUNC))
  434. count ++;
  435. }
  436. module->symtab = (struct rt_module_symtab *)rt_malloc
  437. (count * sizeof(struct rt_module_symtab));
  438. module->nsym = count;
  439. for (i=0, count=0; i<shdr[index].sh_size/sizeof(Elf32_Sym); i++)
  440. {
  441. rt_size_t length;
  442. if ((ELF_ST_BIND(symtab[i].st_info) != STB_GLOBAL) ||
  443. (ELF_ST_TYPE(symtab[i].st_info) != STT_FUNC))
  444. continue;
  445. length = rt_strlen((const char *)(strtab + symtab[i].st_name)) + 1;
  446. module->symtab[count].addr =
  447. (void *)(module->module_space + symtab[i].st_value);
  448. module->symtab[count].name = rt_malloc(length);
  449. rt_memset((void *)module->symtab[count].name, 0, length);
  450. rt_memcpy((void *)module->symtab[count].name,
  451. strtab + symtab[i].st_name,
  452. length);
  453. count ++;
  454. }
  455. }
  456. return module;
  457. }
  458. static struct rt_module* _load_relocated_object(const char *name,
  459. void *module_ptr)
  460. {
  461. rt_uint32_t index, rodata_addr = 0, bss_addr = 0, data_addr = 0;
  462. rt_uint32_t module_addr = 0, module_size = 0;
  463. struct rt_module *module = RT_NULL;
  464. rt_uint8_t *ptr, *strtab, *shstrab;
  465. /* get the ELF image size */
  466. for (index = 0; index < elf_module->e_shnum; index ++)
  467. {
  468. /* text */
  469. if (IS_PROG(shdr[index]) && IS_AX(shdr[index]))
  470. {
  471. module_size += shdr[index].sh_size;
  472. module_addr = shdr[index].sh_addr;
  473. }
  474. /* rodata */
  475. if (IS_PROG(shdr[index]) && IS_ALLOC(shdr[index]))
  476. {
  477. module_size += shdr[index].sh_size;
  478. }
  479. /* data */
  480. if (IS_PROG(shdr[index]) && IS_AW(shdr[index]))
  481. {
  482. module_size += shdr[index].sh_size;
  483. }
  484. /* bss */
  485. if (IS_NOPROG(shdr[index]) && IS_AW(shdr[index]))
  486. {
  487. module_size += shdr[index].sh_size;
  488. }
  489. }
  490. /* no text, data and bss on image */
  491. if (module_size == 0)
  492. return RT_NULL;
  493. /* allocate module */
  494. module = (struct rt_module *)
  495. rt_object_allocate(RT_Object_Class_Module, (const char *)name);
  496. if (module == RT_NULL)
  497. return RT_NULL;
  498. /* allocate module space */
  499. module->module_space = rt_malloc(module_size);
  500. if (module->module_space == RT_NULL)
  501. {
  502. rt_kprintf("Module: allocate space failed.\n");
  503. rt_object_delete(&(module->parent));
  504. return RT_NULL;
  505. }
  506. /* zero all space */
  507. ptr = module->module_space;
  508. rt_memset(ptr, 0, module_size);
  509. /* load text and data section */
  510. for (index = 0; index < elf_module->e_shnum; index ++)
  511. {
  512. /* load text section */
  513. if (IS_PROG(shdr[index]) && IS_AX(shdr[index]))
  514. {
  515. rt_memcpy(ptr,
  516. (rt_uint8_t *)elf_module + shdr[index].sh_offset,
  517. shdr[index].sh_size);
  518. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("load text 0x%x, size %d\n",
  519. ptr, shdr[index].sh_size));
  520. ptr += shdr[index].sh_size;
  521. }
  522. /* load rodata section */
  523. if (IS_PROG(shdr[index]) && IS_ALLOC(shdr[index]))
  524. {
  525. rt_memcpy(ptr,
  526. (rt_uint8_t *)elf_module + shdr[index].sh_offset,
  527. shdr[index].sh_size);
  528. rodata_addr = (rt_uint32_t)ptr;
  529. RT_DEBUG_LOG(RT_DEBUG_MODULE,
  530. ("load rodata 0x%x, size %d, rodata 0x%x\n",
  531. ptr, shdr[index].sh_size, *(rt_uint32_t *)data_addr));
  532. ptr += shdr[index].sh_size;
  533. }
  534. /* load data section */
  535. if (IS_PROG(shdr[index]) && IS_AW(shdr[index]))
  536. {
  537. rt_memcpy(ptr,
  538. (rt_uint8_t *)elf_module + shdr[index].sh_offset,
  539. shdr[index].sh_size);
  540. data_addr = (rt_uint32_t)ptr;
  541. RT_DEBUG_LOG(RT_DEBUG_MODULE,
  542. ("load data 0x%x, size %d, data 0x%x\n",
  543. ptr, shdr[index].sh_size, *(rt_uint32_t *)data_addr));
  544. ptr += shdr[index].sh_size;
  545. }
  546. /* load bss section */
  547. if (IS_NOPROG(shdr[index]) && IS_AW(shdr[index]))
  548. {
  549. rt_memset(ptr, 0, shdr[index].sh_size);
  550. bss_addr = (rt_uint32_t)ptr;
  551. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("load bss 0x%x, size %d,\n",
  552. ptr, shdr[index].sh_size));
  553. }
  554. }
  555. /* set module entry */
  556. module->module_entry =
  557. (rt_uint8_t *)module->module_space + elf_module->e_entry - module_addr;
  558. /* handle relocation section */
  559. for (index = 0; index < elf_module->e_shnum; index ++)
  560. {
  561. rt_uint32_t i, nr_reloc;
  562. Elf32_Sym *symtab;
  563. Elf32_Rel *rel;
  564. if (!IS_REL(shdr[index]))
  565. continue;
  566. /* get relocate item */
  567. rel = (Elf32_Rel *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset);
  568. /* locate .dynsym and .dynstr */
  569. symtab = (Elf32_Sym *)((rt_uint8_t *)module_ptr +
  570. shdr[shdr[index].sh_link].sh_offset);
  571. strtab = (rt_uint8_t *)module_ptr +
  572. shdr[shdr[shdr[index].sh_link].sh_link].sh_offset;
  573. shstrab = (rt_uint8_t *)module_ptr +
  574. shdr[elf_module->e_shstrndx].sh_offset;
  575. nr_reloc = (rt_uint32_t)(shdr[index].sh_size / sizeof(Elf32_Rel));
  576. /* relocate every items */
  577. for (i = 0; i < nr_reloc; i ++)
  578. {
  579. Elf32_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)];
  580. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("relocate symbol: %s\n",
  581. strtab + sym->st_name));
  582. if (sym->st_shndx != STN_UNDEF)
  583. {
  584. if ((ELF_ST_TYPE(sym->st_info) == STT_SECTION) ||
  585. (ELF_ST_TYPE(sym->st_info) == STT_OBJECT))
  586. {
  587. if (rt_strncmp((const char *)(shstrab +
  588. shdr[sym->st_shndx].sh_name), ELF_RODATA, 8) == 0)
  589. {
  590. /* relocate rodata section */
  591. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rodata\n"));
  592. rt_module_arm_relocate(module, rel,
  593. (Elf32_Addr)(rodata_addr + sym->st_value));
  594. }
  595. else if (rt_strncmp((const char*)
  596. (shstrab + shdr[sym->st_shndx].sh_name), ELF_BSS, 5) == 0)
  597. {
  598. /* relocate bss section */
  599. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("bss\n"));
  600. rt_module_arm_relocate(module, rel,
  601. (Elf32_Addr)bss_addr + sym->st_value);
  602. }
  603. else if (rt_strncmp((const char *)(shstrab + shdr[sym->st_shndx].sh_name),
  604. ELF_DATA, 6) == 0)
  605. {
  606. /* relocate data section */
  607. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("data\n"));
  608. rt_module_arm_relocate(module, rel,
  609. (Elf32_Addr)data_addr + sym->st_value);
  610. }
  611. }
  612. }
  613. else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
  614. {
  615. /* relocate function */
  616. rt_module_arm_relocate(module, rel, (Elf32_Addr)((rt_uint8_t *)
  617. module->module_space - module_addr + sym->st_value));
  618. }
  619. else
  620. {
  621. Elf32_Addr addr;
  622. if (ELF32_R_TYPE(rel->r_info) != R_ARM_V4BX)
  623. {
  624. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("relocate symbol: %s\n",
  625. strtab + sym->st_name));
  626. /* need to resolve symbol in kernel symbol table */
  627. addr = rt_module_symbol_find((const char *)(strtab + sym->st_name));
  628. if (addr != (Elf32_Addr)RT_NULL)
  629. {
  630. rt_module_arm_relocate(module, rel, addr);
  631. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("symbol addr 0x%x\n",
  632. addr));
  633. }
  634. else
  635. rt_kprintf("Module: can't find %s in kernel symbol table\n",
  636. strtab + sym->st_name);
  637. }
  638. else
  639. {
  640. rt_module_arm_relocate(module, rel, (Elf32_Addr)((rt_uint8_t*)
  641. module->module_space - module_addr + sym->st_value));
  642. }
  643. }
  644. rel ++;
  645. }
  646. }
  647. return module;
  648. }
  649. /**
  650. * This function will load a module from memory and create a thread for it
  651. *
  652. * @param name the name of module, which shall be unique
  653. * @param module_ptr the memory address of module image
  654. *
  655. * @return the module object
  656. */
  657. rt_module_t rt_module_load(const char *name, void *module_ptr)
  658. {
  659. rt_module_t module;
  660. RT_DEBUG_NOT_IN_INTERRUPT;
  661. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_load: %s ,", name));
  662. /* check ELF header */
  663. if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
  664. rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0)
  665. {
  666. rt_kprintf("Module: magic error\n");
  667. return RT_NULL;
  668. }
  669. /* check ELF class */
  670. if (elf_module->e_ident[EI_CLASS] != ELFCLASS32)
  671. {
  672. rt_kprintf("Module: ELF class error\n");
  673. return RT_NULL;
  674. }
  675. if (elf_module->e_type == ET_REL)
  676. {
  677. module = _load_relocated_object(name, module_ptr);
  678. }
  679. else if (elf_module->e_type == ET_DYN)
  680. {
  681. module = _load_shared_object(name, module_ptr);
  682. }
  683. else
  684. {
  685. rt_kprintf("Module: unsupported elf type\n");
  686. return RT_NULL;
  687. }
  688. if (module == RT_NULL)
  689. return RT_NULL;
  690. /* init module object container */
  691. rt_module_init_object_container(module);
  692. /* increase module reference count */
  693. module->nref ++;
  694. if (elf_module->e_entry != 0)
  695. {
  696. rt_uint32_t *stack_size;
  697. rt_uint8_t *priority;
  698. #ifdef RT_USING_SLAB
  699. /* init module memory allocator */
  700. module->mem_list = RT_NULL;
  701. /* create page array */
  702. module->page_array =
  703. (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info));
  704. module->page_cnt = 0;
  705. #endif
  706. /* get the main thread stack size */
  707. module->stack_size = 2048;
  708. module->thread_priority = RT_THREAD_PRIORITY_MAX - 2;
  709. /* create module thread */
  710. module->module_thread =
  711. rt_thread_create(name,
  712. (void(*)(void *))module->module_entry,
  713. RT_NULL,
  714. module->stack_size,
  715. module->thread_priority,
  716. 10);
  717. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("thread entry 0x%x\n",
  718. module->module_entry));
  719. /* set module id */
  720. module->module_thread->module_id = (void *)module;
  721. module->parent.flag = RT_MODULE_FLAG_WITHENTRY;
  722. /* startup module thread */
  723. rt_thread_startup(module->module_thread);
  724. }
  725. else
  726. {
  727. /* without entry point */
  728. module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY;
  729. }
  730. #ifdef RT_USING_HOOK
  731. if (rt_module_load_hook != RT_NULL)
  732. {
  733. rt_module_load_hook(module);
  734. }
  735. #endif
  736. return module;
  737. }
  738. #ifdef RT_USING_DFS
  739. #include <dfs_posix.h>
  740. static char* _module_name(const char *path)
  741. {
  742. const char *first, *end, *ptr;
  743. char *name;
  744. int size;
  745. ptr = (char *)path;
  746. first = ptr;
  747. end = path + rt_strlen(path);
  748. while (*ptr != '\0')
  749. {
  750. if (*ptr == '/')
  751. first = ptr + 1;
  752. if (*ptr == '.')
  753. end = ptr - 1;
  754. ptr ++;
  755. }
  756. size = end - first + 1;
  757. name = rt_malloc(size);
  758. rt_strncpy(name, first, size);
  759. name[size] = '\0';
  760. return name;
  761. }
  762. /**
  763. * This function will load a module from a file
  764. *
  765. * @param path the full path of application module
  766. *
  767. * @return the module object
  768. */
  769. rt_module_t rt_module_open(const char *path)
  770. {
  771. int fd, length;
  772. struct rt_module *module;
  773. struct stat s;
  774. char *buffer, *offset_ptr;
  775. char *name;
  776. RT_DEBUG_NOT_IN_INTERRUPT;
  777. /* check parameters */
  778. RT_ASSERT(path != RT_NULL);
  779. if (stat(path, &s) !=0)
  780. {
  781. rt_kprintf("Module: access %s failed\n", path);
  782. return RT_NULL;
  783. }
  784. buffer = (char *)rt_malloc(s.st_size);
  785. if (buffer == RT_NULL)
  786. {
  787. rt_kprintf("Module: out of memory\n");
  788. return RT_NULL;
  789. }
  790. offset_ptr = buffer;
  791. fd = open(path, O_RDONLY, 0);
  792. if (fd < 0)
  793. {
  794. rt_kprintf("Module: open %s failed\n", path);
  795. rt_free(buffer);
  796. return RT_NULL;
  797. }
  798. do
  799. {
  800. length = read(fd, offset_ptr, 4096);
  801. if (length > 0)
  802. {
  803. offset_ptr += length;
  804. }
  805. }while (length > 0);
  806. /* close fd */
  807. close(fd);
  808. if ((rt_uint32_t)offset_ptr - (rt_uint32_t)buffer != s.st_size)
  809. {
  810. rt_kprintf("Module: read file failed\n");
  811. rt_free(buffer);
  812. return RT_NULL;
  813. }
  814. name = _module_name(path);
  815. module = rt_module_load(name, (void *)buffer);
  816. rt_free(buffer);
  817. rt_free(name);
  818. return module;
  819. }
  820. #if defined(RT_USING_FINSH)
  821. #include <finsh.h>
  822. FINSH_FUNCTION_EXPORT_ALIAS(rt_module_open, exec, exec module from a file);
  823. #endif
  824. #endif
  825. /**
  826. * This function will destroy a module and release its resource.
  827. *
  828. * @param module the module to be destroyed.
  829. *
  830. * @return the operation status, RT_EOK on OK; -RT_ERROR on error
  831. */
  832. rt_err_t rt_module_destroy(rt_module_t module)
  833. {
  834. int i;
  835. struct rt_object *object;
  836. struct rt_list_node *list;
  837. RT_DEBUG_NOT_IN_INTERRUPT;
  838. /* check parameter */
  839. RT_ASSERT(module != RT_NULL);
  840. RT_ASSERT(module->nref == 0);
  841. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_destroy: %8.*s\n",
  842. RT_NAME_MAX, module->parent.name));
  843. /* module has entry point */
  844. if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
  845. {
  846. #ifdef RT_USING_SEMAPHORE
  847. /* delete semaphores */
  848. list = &module->module_object[RT_Object_Class_Thread].object_list;
  849. while (list->next != list)
  850. {
  851. object = rt_list_entry(list->next, struct rt_object, list);
  852. if (rt_object_is_systemobject(object) == RT_TRUE)
  853. {
  854. /* detach static object */
  855. rt_sem_detach((rt_sem_t)object);
  856. }
  857. else
  858. {
  859. /* delete dynamic object */
  860. rt_sem_delete((rt_sem_t)object);
  861. }
  862. }
  863. #endif
  864. #ifdef RT_USING_MUTEX
  865. /* delete mutexs*/
  866. list = &module->module_object[RT_Object_Class_Mutex].object_list;
  867. while (list->next != list)
  868. {
  869. object = rt_list_entry(list->next, struct rt_object, list);
  870. if (rt_object_is_systemobject(object) == RT_TRUE)
  871. {
  872. /* detach static object */
  873. rt_mutex_detach((rt_mutex_t)object);
  874. }
  875. else
  876. {
  877. /* delete dynamic object */
  878. rt_mutex_delete((rt_mutex_t)object);
  879. }
  880. }
  881. #endif
  882. #ifdef RT_USING_EVENT
  883. /* delete mailboxs */
  884. list = &module->module_object[RT_Object_Class_Event].object_list;
  885. while (list->next != list)
  886. {
  887. object = rt_list_entry(list->next, struct rt_object, list);
  888. if (rt_object_is_systemobject(object) == RT_TRUE)
  889. {
  890. /* detach static object */
  891. rt_event_detach((rt_event_t)object);
  892. }
  893. else
  894. {
  895. /* delete dynamic object */
  896. rt_event_delete((rt_event_t)object);
  897. }
  898. }
  899. #endif
  900. #ifdef RT_USING_MAILBOX
  901. /* delete mailboxs */
  902. list = &module->module_object[RT_Object_Class_MailBox].object_list;
  903. while (list->next != list)
  904. {
  905. object = rt_list_entry(list->next, struct rt_object, list);
  906. if (rt_object_is_systemobject(object) == RT_TRUE)
  907. {
  908. /* detach static object */
  909. rt_mb_detach((rt_mailbox_t)object);
  910. }
  911. else
  912. {
  913. /* delete dynamic object */
  914. rt_mb_delete((rt_mailbox_t)object);
  915. }
  916. }
  917. #endif
  918. #ifdef RT_USING_MESSAGEQUEUE
  919. /* delete msgqueues */
  920. list = &module->module_object[RT_Object_Class_MessageQueue].object_list;
  921. while (list->next != list)
  922. {
  923. object = rt_list_entry(list->next, struct rt_object, list);
  924. if (rt_object_is_systemobject(object) == RT_TRUE)
  925. {
  926. /* detach static object */
  927. rt_mq_detach((rt_mq_t)object);
  928. }
  929. else
  930. {
  931. /* delete dynamic object */
  932. rt_mq_delete((rt_mq_t)object);
  933. }
  934. }
  935. #endif
  936. #ifdef RT_USING_MEMPOOL
  937. /* delete mempools */
  938. list = &module->module_object[RT_Object_Class_MemPool].object_list;
  939. while (list->next != list)
  940. {
  941. object = rt_list_entry(list->next, struct rt_object, list);
  942. if (rt_object_is_systemobject(object) == RT_TRUE)
  943. {
  944. /* detach static object */
  945. rt_mp_detach((rt_mp_t)object);
  946. }
  947. else
  948. {
  949. /* delete dynamic object */
  950. rt_mp_delete((rt_mp_t)object);
  951. }
  952. }
  953. #endif
  954. #ifdef RT_USING_DEVICE
  955. /* delete devices */
  956. list = &module->module_object[RT_Object_Class_Device].object_list;
  957. while (list->next != list)
  958. {
  959. object = rt_list_entry(list->next, struct rt_object, list);
  960. rt_device_unregister((rt_device_t)object);
  961. }
  962. #endif
  963. /* delete timers */
  964. list = &module->module_object[RT_Object_Class_Timer].object_list;
  965. while (list->next != list)
  966. {
  967. object = rt_list_entry(list->next, struct rt_object, list);
  968. if (rt_object_is_systemobject(object) == RT_TRUE)
  969. {
  970. /* detach static object */
  971. rt_timer_detach((rt_timer_t)object);
  972. }
  973. else
  974. {
  975. /* delete dynamic object */
  976. rt_timer_delete((rt_timer_t)object);
  977. }
  978. }
  979. }
  980. #ifdef RT_USING_SLAB
  981. if (module->page_cnt > 0)
  982. {
  983. struct rt_page_info *page = (struct rt_page_info *)module->page_array;
  984. rt_kprintf("Module: warning - memory still hasn't been free finished\n");
  985. while (module->page_cnt != 0)
  986. {
  987. rt_module_free_page(module, page[0].page_ptr, page[0].npage);
  988. }
  989. }
  990. #endif
  991. /* release module space memory */
  992. rt_free(module->module_space);
  993. /* release module symbol table */
  994. for (i = 0; i < module->nsym; i ++)
  995. {
  996. rt_free((void *)module->symtab[i].name);
  997. }
  998. if (module->symtab != RT_NULL)
  999. rt_free(module->symtab);
  1000. #ifdef RT_USING_SLAB
  1001. if (module->page_array != RT_NULL)
  1002. rt_free(module->page_array);
  1003. #endif
  1004. /* delete module object */
  1005. rt_object_delete((rt_object_t)module);
  1006. return RT_EOK;
  1007. }
  1008. /**
  1009. * This function will unload a module from memory and release resources
  1010. *
  1011. * @param module the module to be unloaded
  1012. *
  1013. * @return the operation status, RT_EOK on OK; -RT_ERROR on error
  1014. */
  1015. rt_err_t rt_module_unload(rt_module_t module)
  1016. {
  1017. int i;
  1018. rt_err_t result;
  1019. struct rt_object *object;
  1020. struct rt_list_node *list;
  1021. RT_DEBUG_NOT_IN_INTERRUPT;
  1022. /* check parameter */
  1023. if (module == RT_NULL)
  1024. return -RT_ERROR;
  1025. rt_enter_critical();
  1026. if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
  1027. {
  1028. /* delete all sub-threads */
  1029. list = &module->module_object[RT_Object_Class_Thread].object_list;
  1030. while (list->next != list)
  1031. {
  1032. object = rt_list_entry(list->next, struct rt_object, list);
  1033. if (rt_object_is_systemobject(object) == RT_TRUE)
  1034. {
  1035. /* detach static object */
  1036. rt_thread_detach((rt_thread_t)object);
  1037. }
  1038. else
  1039. {
  1040. /* delete dynamic object */
  1041. rt_thread_delete((rt_thread_t)object);
  1042. }
  1043. }
  1044. /* delete the main thread of module */
  1045. if (module->module_thread != RT_NULL)
  1046. {
  1047. rt_thread_delete(module->module_thread);
  1048. }
  1049. }
  1050. rt_exit_critical();
  1051. #ifdef RT_USING_HOOK
  1052. if (rt_module_unload_hook != RT_NULL)
  1053. {
  1054. rt_module_unload_hook(module);
  1055. }
  1056. #endif
  1057. return RT_EOK;
  1058. }
  1059. /**
  1060. * This function will find the specified module.
  1061. *
  1062. * @param name the name of module finding
  1063. *
  1064. * @return the module
  1065. */
  1066. rt_module_t rt_module_find(const char *name)
  1067. {
  1068. struct rt_object_information *information;
  1069. struct rt_object *object;
  1070. struct rt_list_node *node;
  1071. extern struct rt_object_information rt_object_container[];
  1072. RT_DEBUG_NOT_IN_INTERRUPT;
  1073. /* enter critical */
  1074. rt_enter_critical();
  1075. /* try to find device object */
  1076. information = &rt_object_container[RT_Object_Class_Module];
  1077. for (node = information->object_list.next;
  1078. node != &(information->object_list);
  1079. node = node->next)
  1080. {
  1081. object = rt_list_entry(node, struct rt_object, list);
  1082. if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
  1083. {
  1084. /* leave critical */
  1085. rt_exit_critical();
  1086. return (rt_module_t)object;
  1087. }
  1088. }
  1089. /* leave critical */
  1090. rt_exit_critical();
  1091. /* not found */
  1092. return RT_NULL;
  1093. }
  1094. #ifdef RT_USING_SLAB
  1095. /*
  1096. * This function will allocate the numbers page with specified size
  1097. * in page memory.
  1098. *
  1099. * @param size the size of memory to be allocated.
  1100. * @note this function is used for RT-Thread Application Module
  1101. */
  1102. static void *rt_module_malloc_page(rt_size_t npages)
  1103. {
  1104. void *chunk;
  1105. struct rt_page_info *page;
  1106. rt_module_t self_module;
  1107. self_module = rt_module_self();
  1108. RT_ASSERT(self_module != RT_NULL);
  1109. chunk = rt_page_alloc(npages);
  1110. if (chunk == RT_NULL)
  1111. return RT_NULL;
  1112. page = (struct rt_page_info *)self_module->page_array;
  1113. page[self_module->page_cnt].page_ptr = chunk;
  1114. page[self_module->page_cnt].npage = npages;
  1115. self_module->page_cnt ++;
  1116. RT_ASSERT(self_module->page_cnt <= PAGE_COUNT_MAX);
  1117. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_malloc_page 0x%x %d\n",
  1118. chunk, npages));
  1119. return chunk;
  1120. }
  1121. /*
  1122. * This function will release the previously allocated memory page
  1123. * by rt_malloc_page.
  1124. *
  1125. * @param page_ptr the page address to be released.
  1126. * @param npages the number of page shall be released.
  1127. *
  1128. * @note this function is used for RT-Thread Application Module
  1129. */
  1130. static void rt_module_free_page(rt_module_t module,
  1131. void *page_ptr,
  1132. rt_size_t npages)
  1133. {
  1134. int i, index;
  1135. struct rt_page_info *page;
  1136. rt_module_t self_module;
  1137. self_module = rt_module_self();
  1138. RT_ASSERT(self_module != RT_NULL);
  1139. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_free_page 0x%x %d\n",
  1140. page_ptr, npages));
  1141. rt_page_free(page_ptr, npages);
  1142. page = (struct rt_page_info *)module->page_array;
  1143. for (i = 0; i < module->page_cnt; i ++)
  1144. {
  1145. if (page[i].page_ptr == page_ptr)
  1146. {
  1147. if (page[i].npage == npages + 1)
  1148. {
  1149. page[i].page_ptr +=
  1150. npages * RT_MM_PAGE_SIZE / sizeof(rt_uint32_t);
  1151. page[i].npage -= npages;
  1152. }
  1153. else if (page[i].npage == npages)
  1154. {
  1155. for (index = i; index < module->page_cnt-1; index ++)
  1156. {
  1157. page[index].page_ptr = page[index + 1].page_ptr;
  1158. page[index].npage = page[index + 1].npage;
  1159. }
  1160. page[module->page_cnt - 1].page_ptr = RT_NULL;
  1161. page[module->page_cnt - 1].npage = 0;
  1162. module->page_cnt --;
  1163. }
  1164. else
  1165. RT_ASSERT(RT_FALSE);
  1166. self_module->page_cnt --;
  1167. return;
  1168. }
  1169. }
  1170. /* should not get here */
  1171. RT_ASSERT(RT_FALSE);
  1172. }
  1173. /**
  1174. * rt_module_malloc - allocate memory block in free list
  1175. */
  1176. void *rt_module_malloc(rt_size_t size)
  1177. {
  1178. struct rt_mem_head *b, *n, *up;
  1179. struct rt_mem_head **prev;
  1180. rt_uint32_t npage;
  1181. rt_size_t nunits;
  1182. rt_module_t self_module;
  1183. self_module = rt_module_self();
  1184. RT_ASSERT(self_module != RT_NULL);
  1185. RT_DEBUG_NOT_IN_INTERRUPT;
  1186. nunits = (size + sizeof(struct rt_mem_head) - 1) /
  1187. sizeof(struct rt_mem_head)
  1188. + 1;
  1189. RT_ASSERT(size != 0);
  1190. RT_ASSERT(nunits != 0);
  1191. rt_sem_take(&mod_sem, RT_WAITING_FOREVER);
  1192. for (prev = (struct rt_mem_head **)&self_module->mem_list;
  1193. (b = *prev) != RT_NULL;
  1194. prev = &(b->next))
  1195. {
  1196. if (b->size > nunits)
  1197. {
  1198. /* split memory */
  1199. n = b + nunits;
  1200. n->next = b->next;
  1201. n->size = b->size - nunits;
  1202. b->size = nunits;
  1203. *prev = n;
  1204. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_malloc 0x%x, %d\n",
  1205. b + 1, size));
  1206. rt_sem_release(&mod_sem);
  1207. return (void *)(b + 1);
  1208. }
  1209. if (b->size == nunits)
  1210. {
  1211. /* this node fit, remove this node */
  1212. *prev = b->next;
  1213. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_malloc 0x%x, %d\n",
  1214. b + 1, size));
  1215. rt_sem_release(&mod_sem);
  1216. return (void *)(b + 1);
  1217. }
  1218. }
  1219. /* allocate pages from system heap */
  1220. npage = (size + sizeof(struct rt_mem_head) + RT_MM_PAGE_SIZE - 1) /
  1221. RT_MM_PAGE_SIZE;
  1222. if ((up = (struct rt_mem_head *)rt_module_malloc_page(npage)) == RT_NULL)
  1223. return RT_NULL;
  1224. up->size = npage * RT_MM_PAGE_SIZE / sizeof(struct rt_mem_head);
  1225. for (prev = (struct rt_mem_head **)&self_module->mem_list;
  1226. (b = *prev) != RT_NULL;
  1227. prev = &(b->next))
  1228. {
  1229. if (b > up + up->size)
  1230. break;
  1231. }
  1232. up->next = b;
  1233. *prev = up;
  1234. rt_sem_release(&mod_sem);
  1235. return rt_module_malloc(size);
  1236. }
  1237. /**
  1238. * rt_module_free - free memory block in free list
  1239. */
  1240. void rt_module_free(rt_module_t module, void *addr)
  1241. {
  1242. struct rt_mem_head *b, *n, *r;
  1243. struct rt_mem_head **prev;
  1244. RT_DEBUG_NOT_IN_INTERRUPT;
  1245. RT_ASSERT(addr);
  1246. RT_ASSERT((((rt_uint32_t)addr) & (sizeof(struct rt_mem_head) -1)) == 0);
  1247. RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_free 0x%x\n", addr));
  1248. rt_sem_take(&mod_sem, RT_WAITING_FOREVER);
  1249. n = (struct rt_mem_head *)addr - 1;
  1250. prev = (struct rt_mem_head **)&module->mem_list;
  1251. while ((b = *prev) != RT_NULL)
  1252. {
  1253. RT_ASSERT(b->size > 0);
  1254. RT_ASSERT(b > n || b + b->size <= n);
  1255. if (b + b->size == n && ((rt_uint32_t)n % RT_MM_PAGE_SIZE != 0))
  1256. {
  1257. if (b + (b->size + n->size) == b->next)
  1258. {
  1259. b->size += b->next->size + n->size;
  1260. b->next = b->next->next;
  1261. }
  1262. else
  1263. b->size += n->size;
  1264. if ((rt_uint32_t)b % RT_MM_PAGE_SIZE == 0)
  1265. {
  1266. int npage =
  1267. b->size * sizeof(struct rt_page_info) / RT_MM_PAGE_SIZE;
  1268. if (npage > 0)
  1269. {
  1270. if ((b->size * sizeof(struct rt_page_info) % RT_MM_PAGE_SIZE) != 0)
  1271. {
  1272. rt_size_t nunits = npage *
  1273. RT_MM_PAGE_SIZE /
  1274. sizeof(struct rt_mem_head);
  1275. /* split memory */
  1276. r = b + nunits;
  1277. r->next = b->next;
  1278. r->size = b->size - nunits;
  1279. *prev = r;
  1280. }
  1281. else
  1282. {
  1283. *prev = b->next;
  1284. }
  1285. rt_module_free_page(module, b, npage);
  1286. }
  1287. }
  1288. /* unlock */
  1289. rt_sem_release(&mod_sem);
  1290. return;
  1291. }
  1292. if (b == n + n->size)
  1293. {
  1294. n->size = b->size + n->size;
  1295. n->next = b->next;
  1296. if ((rt_uint32_t)n % RT_MM_PAGE_SIZE == 0)
  1297. {
  1298. int npage =
  1299. n->size * sizeof(struct rt_page_info) / RT_MM_PAGE_SIZE;
  1300. if (npage > 0)
  1301. {
  1302. if ((n->size * sizeof(struct rt_page_info) % RT_MM_PAGE_SIZE) != 0)
  1303. {
  1304. rt_size_t nunits = npage *
  1305. RT_MM_PAGE_SIZE /
  1306. sizeof(struct rt_mem_head);
  1307. /* split memory */
  1308. r = n + nunits;
  1309. r->next = n->next;
  1310. r->size = n->size - nunits;
  1311. *prev = r;
  1312. }
  1313. else
  1314. *prev = n->next;
  1315. rt_module_free_page(module, n, npage);
  1316. }
  1317. }
  1318. else
  1319. {
  1320. *prev = n;
  1321. }
  1322. /* unlock */
  1323. rt_sem_release(&mod_sem);
  1324. return;
  1325. }
  1326. if (b > n + n->size)
  1327. break;
  1328. prev = &(b->next);
  1329. }
  1330. if ((rt_uint32_t)n % RT_MM_PAGE_SIZE == 0)
  1331. {
  1332. int npage = n->size * sizeof(struct rt_page_info) / RT_MM_PAGE_SIZE;
  1333. if (npage > 0)
  1334. {
  1335. rt_module_free_page(module, n, npage);
  1336. if (n->size % RT_MM_PAGE_SIZE != 0)
  1337. {
  1338. rt_size_t nunits =
  1339. npage * RT_MM_PAGE_SIZE / sizeof(struct rt_mem_head);
  1340. /* split memory */
  1341. r = n + nunits;
  1342. r->next = b;
  1343. r->size = n->size - nunits;
  1344. *prev = r;
  1345. }
  1346. else
  1347. {
  1348. *prev = b;
  1349. }
  1350. }
  1351. }
  1352. else
  1353. {
  1354. n->next = b;
  1355. *prev = n;
  1356. }
  1357. /* unlock */
  1358. rt_sem_release(&mod_sem);
  1359. }
  1360. /**
  1361. * rt_module_realloc - realloc memory block in free list
  1362. */
  1363. void *rt_module_realloc(void *ptr, rt_size_t size)
  1364. {
  1365. struct rt_mem_head *b, *p, *prev, *tmpp;
  1366. rt_size_t nunits;
  1367. rt_module_t self_module;
  1368. self_module = rt_module_self();
  1369. RT_ASSERT(self_module != RT_NULL);
  1370. RT_DEBUG_NOT_IN_INTERRUPT;
  1371. if (!ptr)
  1372. return rt_module_malloc(size);
  1373. if (size == 0)
  1374. {
  1375. rt_module_free(self_module, ptr);
  1376. return RT_NULL;
  1377. }
  1378. nunits = (size + sizeof(struct rt_mem_head) - 1) /
  1379. sizeof(struct rt_mem_head)
  1380. +1;
  1381. b = (struct rt_mem_head *)ptr - 1;
  1382. if (nunits <= b->size)
  1383. {
  1384. /* new size is smaller or equal then before */
  1385. if (nunits == b->size)
  1386. return ptr;
  1387. else
  1388. {
  1389. p = b + nunits;
  1390. p->size = b->size - nunits;
  1391. b->size = nunits;
  1392. rt_module_free(self_module, (void *)(p + 1));
  1393. return (void *)(b + 1);
  1394. }
  1395. }
  1396. else
  1397. {
  1398. /* more space then required */
  1399. prev = (struct rt_mem_head *)self_module->mem_list;
  1400. for (p = prev->next;
  1401. p != (b->size + b) && p != RT_NULL;
  1402. prev = p, p = p->next)
  1403. {
  1404. break;
  1405. }
  1406. /* available block after ap in freelist */
  1407. if (p != RT_NULL &&
  1408. (p->size >= (nunits - (b->size))) &&
  1409. p == (b + b->size))
  1410. {
  1411. /* perfect match */
  1412. if (p->size == (nunits - (b->size)))
  1413. {
  1414. b->size = nunits;
  1415. prev->next = p->next;
  1416. }
  1417. else /* more space then required, split block */
  1418. {
  1419. /* pointer to old header */
  1420. tmpp = p;
  1421. p = b + nunits;
  1422. /* restoring old pointer */
  1423. p->next = tmpp->next;
  1424. /* new size for p */
  1425. p->size = tmpp->size + b->size - nunits;
  1426. b->size = nunits;
  1427. prev->next = p;
  1428. }
  1429. self_module->mem_list = (void *)prev;
  1430. return (void *)(b + 1);
  1431. }
  1432. else /* allocate new memory and copy old data */
  1433. {
  1434. if ((p = rt_module_malloc(size)) == RT_NULL)
  1435. return RT_NULL;
  1436. rt_memmove(p, (b+1), ((b->size) * sizeof(struct rt_mem_head)));
  1437. rt_module_free(self_module, (void *)(b + 1));
  1438. return (void *)(p);
  1439. }
  1440. }
  1441. }
  1442. #ifdef RT_USING_FINSH
  1443. #include <finsh.h>
  1444. void list_memlist(const char *name)
  1445. {
  1446. rt_module_t module;
  1447. struct rt_mem_head **prev;
  1448. struct rt_mem_head *b;
  1449. module = rt_module_find(name);
  1450. if (module == RT_NULL)
  1451. return;
  1452. for (prev = (struct rt_mem_head **)&module->mem_list;
  1453. (b = *prev) != RT_NULL;
  1454. prev = &(b->next))
  1455. {
  1456. rt_kprintf("0x%x--%d\n", b, b->size * sizeof(struct rt_mem_head));
  1457. }
  1458. }
  1459. FINSH_FUNCTION_EXPORT(list_memlist, list module free memory information)
  1460. void list_mempage(const char *name)
  1461. {
  1462. rt_module_t module;
  1463. struct rt_page_info *page;
  1464. int i;
  1465. module = rt_module_find(name);
  1466. if (module == RT_NULL)
  1467. return;
  1468. page = (struct rt_page_info *)module->page_array;
  1469. for (i = 0; i < module->page_cnt; i ++)
  1470. {
  1471. rt_kprintf("0x%x--%d\n", page[i].page_ptr, page[i].npage);
  1472. }
  1473. }
  1474. FINSH_FUNCTION_EXPORT(list_mempage, list module using memory page information)
  1475. #endif
  1476. #endif
  1477. #endif