module.c 38 KB

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