module.c 39 KB

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