Browse Source

support kernel symbol link in module system

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1022 bbd45198-f89e-11dd-88c7-29a3b14d5316
qiuyiuestc 14 years ago
parent
commit
9403fd7fc5
4 changed files with 267 additions and 6 deletions
  1. 16 0
      src/kservice.c
  2. 71 6
      src/module.c
  3. 1 0
      src/module.h
  4. 179 0
      src/rtm.c

+ 16 - 0
src/kservice.c

@@ -362,6 +362,21 @@ rt_ubase_t rt_strncmp(const char * cs, const char * ct, rt_ubase_t count)
 	return __res;
 }
 
+/**
+ * This function will compare two strings without specified length
+ *
+ * @param cs the string to be compared
+ * @param ct the string to be compared
+ *
+ * @return the result
+ */
+rt_uint32_t rt_strcmp (const char *cs, const char *ct)
+{
+	while (*cs && *cs == *ct)
+		cs++, ct++;
+	return (*cs - *ct);
+}
+
 /**
  * This function will return the length of a string, which terminate will
  * null character.
@@ -970,6 +985,7 @@ size_t strlen(const char *s) __attribute__((weak, alias("rt_strlen")));
 char *strstr(const char *s1,const char *s2) __attribute__((weak, alias("rt_strstr")));
 int strcasecmp(const char *a, const char *b) __attribute__((weak, alias("rt_strcasecmp")));
 char *strncpy(char *dest, const char *src, size_t n) __attribute__((weak, alias("rt_strncpy")));
+char *strcpy(char *dest, const char *src, size_t n) __attribute__((weak, alias("rt_strcpy")));
 int strncmp(const char *cs, const char *ct, size_t count) __attribute__((weak, alias("rt_strncmp")));
 #ifdef RT_USING_HEAP
 char *strdup(const char *s) __attribute__((weak, alias("rt_strdup")));

+ 71 - 6
src/module.c

@@ -36,6 +36,38 @@
 #define IS_AW(s)			((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_WRITE))
 
 static struct rt_module* rt_current_module = RT_NULL;
+rt_list_t rt_module_symbol_list;
+struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL, *_rt_module_symtab_end = RT_NULL;
+
+/**
+ * @ingroup SystemInit
+ *
+ * This function will init system module
+ *
+ */
+void rt_system_module_init(void)
+{
+	extern int __rtmsymtab_start;
+	extern int __rtmsymtab_end;
+
+	_rt_module_symtab_begin = (struct rt_module_symtab *)&__rtmsymtab_start;
+	_rt_module_symtab_end   = (struct rt_module_symtab *)&__rtmsymtab_end;
+
+	rt_list_init(&rt_module_symbol_list);
+}
+
+static rt_uint32_t rt_module_symbol_find(const rt_uint8_t* sym_str)
+{
+	/* find in kernel symbol table */
+	struct rt_module_symtab* index;
+	for (index = _rt_module_symtab_begin; index != _rt_module_symtab_end; index ++)
+	{
+		if (rt_strcmp(index->name, (const char*)sym_str) == 0)
+			return index->addr;
+	}
+
+	return 0;
+}
 
 /**
  * This function will return self module object
@@ -190,19 +222,31 @@ rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr)
 {
 	rt_uint32_t index;
 	rt_uint32_t module_size = 0;
-	struct rt_module* module = RT_NULL;
+	rt_module_t module = RT_NULL;
 	rt_uint8_t *ptr, *strtab;
+	rt_bool_t linked = RT_FALSE;
 
 #ifdef RT_MODULE_DEBUG
 	rt_kprintf("rt_module_load: %s\n", name);
 #endif
 	/* check ELF header */
-	if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 ||
-		elf_module->e_ident[EI_CLASS] != ELFCLASS32)
+	if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) == 0)
+	{
+		/* rtmlinke finished */
+		linked = RT_TRUE;
+	}
+	else	 if (rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0)
 	{
 		rt_kprintf(" module magic error\n");
 		return RT_NULL;
 	}
+
+	/* check ELF class */
+	if(elf_module->e_ident[EI_CLASS] != ELFCLASS32)
+	{
+		rt_kprintf(" module class error\n");
+		return RT_NULL;
+	}
 	
 	/* get the ELF image size */
 	for (index = 0; index < elf_module->e_phnum; index++)
@@ -273,6 +317,23 @@ rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr)
 				{	
 					rt_module_arm_relocate(module, rel, (Elf32_Addr)((rt_uint8_t*)module->module_space + sym->st_value));
 				}
+				else if(linked == RT_FALSE)
+				{
+					Elf32_Addr addr;
+#ifdef RT_MODULE_DEBUG
+					rt_kprintf("unresolved relocate symbol: %s\n", strtab + sym->st_name);
+#endif
+					/* need to resolve symbol in kernel symbol table */
+					addr = rt_module_symbol_find(strtab + sym->st_name);
+					if (addr == 0)
+					{
+						rt_kprintf("can't find %s in kernel symbol table\n", strtab + sym->st_name);
+						rt_object_delete(&(module->parent));
+						rt_free(module);
+						return RT_NULL;
+					}	
+					rt_module_arm_relocate(module, rel, addr);
+				}
 				rel ++;
 			}
 		}
@@ -308,7 +369,7 @@ rt_module_t rt_module_load_from_file(const rt_uint8_t* name, const char* filenam
 {
 	int fd, length;
 	struct rt_module* module;
-	struct stat s;
+	struct _stat s;
 	char *buffer;
 	
 	stat(filename, &s);
@@ -341,7 +402,6 @@ rt_module_t rt_module_load_from_file(const rt_uint8_t* name, const char* filenam
  */
 rt_err_t rt_module_unload(rt_module_t module)
 {
-	int i;
 	struct rt_object* object;
 	struct rt_list_node *list;
 
@@ -563,7 +623,12 @@ rt_module_t rt_module_find(char* name)
 #if defined(RT_USING_FINSH)
 #include <finsh.h>
 
-FINSH_FUNCTION_EXPORT(rt_module_load_from_file, load module from file);
+void run_module(const rt_uint8_t* name, const char* filename)
+{
+	rt_module_load_from_file(name, filename);
+}
+
+FINSH_FUNCTION_EXPORT(run_module, load module from file);
 #endif
 
 #endif

+ 1 - 0
src/module.h

@@ -17,6 +17,7 @@ typedef rt_uint16_t	Elf32_Half;	/* Unsigned medium integer */
 #define	ELFMAG2		'L'			/* e_ident[EI_MAG2] */
 #define	ELFMAG3		'F'			/* e_ident[EI_MAG3] */
 #define	RTMMAG		"\177RTM"	/* magic */
+#define	ELFMAG		"\177ELF"		/* magic */
 #define	SELFMAG		4			/* size of magic */
 
 #define EI_CLASS	4		/* file class */

+ 179 - 0
src/rtm.c

@@ -13,4 +13,183 @@
  */
 
 #include <rtthread.h> 
+
+/* some buildin kernel symbol */
+
+#ifdef RT_USING_MODULE
 #include <rtm.h>
+
+/*
+ * thread  interface symbol 
+ */
+RTM_EXPORT(rt_thread_init)
+RTM_EXPORT(rt_thread_detach)
+RTM_EXPORT(rt_thread_create)
+RTM_EXPORT(rt_thread_self)
+RTM_EXPORT(rt_thread_find)
+RTM_EXPORT(rt_thread_startup)
+RTM_EXPORT(rt_thread_delete)
+RTM_EXPORT(rt_thread_yield)
+RTM_EXPORT(rt_thread_delay)
+RTM_EXPORT(rt_thread_control)
+RTM_EXPORT(rt_thread_suspend)
+RTM_EXPORT(rt_thread_resume)
+RTM_EXPORT(rt_thread_timeout)
+
+#ifdef RT_USING_SEMAPHORE
+/*
+ * semaphore interface symbol
+ */
+RTM_EXPORT(rt_sem_init)
+RTM_EXPORT(rt_sem_detach)
+RTM_EXPORT(rt_sem_create)
+RTM_EXPORT(rt_sem_delete)
+RTM_EXPORT(rt_sem_take)
+RTM_EXPORT(rt_sem_trytake)
+RTM_EXPORT(rt_sem_release)
+RTM_EXPORT(rt_sem_control)
+#endif
+
+#ifdef RT_USING_MUTEX
+/*
+ * mutex interface symbol
+ */
+RTM_EXPORT(rt_mutex_init)
+RTM_EXPORT(rt_mutex_detach)
+RTM_EXPORT(rt_mutex_create)
+RTM_EXPORT(rt_mutex_delete)
+RTM_EXPORT(rt_mutex_take)
+RTM_EXPORT(rt_mutex_release)
+RTM_EXPORT(rt_mutex_control)
+#endif
+
+#ifdef RT_USING_EVENT
+/*
+ * event interface symbol
+ */
+RTM_EXPORT(rt_event_init)
+RTM_EXPORT(rt_event_detach)
+RTM_EXPORT(rt_event_create)
+RTM_EXPORT(rt_event_delete)
+RTM_EXPORT(rt_event_send)
+RTM_EXPORT(rt_event_recv)
+RTM_EXPORT(rt_event_control) 
+#endif
+
+#ifdef RT_USING_MAILBOX
+/*
+ * mailbox interface symbol
+ */
+RTM_EXPORT(rt_mb_init)
+RTM_EXPORT(rt_mb_detach)
+RTM_EXPORT(rt_mb_create)
+RTM_EXPORT(rt_mb_delete)
+RTM_EXPORT(rt_mb_send)
+RTM_EXPORT(rt_mb_recv)
+RTM_EXPORT(rt_mb_control) 
+#endif
+
+#ifdef RT_USING_MESSAGEQUEUE
+/*
+ * message queue interface symbol
+ */
+RTM_EXPORT(rt_mq_init)
+RTM_EXPORT(rt_mq_detach)
+RTM_EXPORT(rt_mq_create)
+RTM_EXPORT(rt_mq_delete)
+RTM_EXPORT(rt_mq_send)
+RTM_EXPORT(rt_mq_urgent)
+RTM_EXPORT(rt_mq_recv)  
+RTM_EXPORT(rt_mq_control)  
+#endif
+
+#ifdef RT_USING_MEMPOOL
+/*
+ * memory pool interface symbol
+ */
+RTM_EXPORT(rt_mp_init)
+RTM_EXPORT(rt_mp_detach)
+RTM_EXPORT(rt_mp_create)
+RTM_EXPORT(rt_mp_delete)
+RTM_EXPORT(rt_mp_alloc)
+RTM_EXPORT(rt_mp_free)
+#endif
+
+#ifdef RT_USING_HEAP
+/*
+ * heap memory interface symbol
+ */
+RTM_EXPORT(rt_malloc)
+RTM_EXPORT(rt_free)
+RTM_EXPORT(rt_realloc)
+RTM_EXPORT(rt_calloc)
+#endif
+/*
+ * clock & timer interface symbol
+ */
+RTM_EXPORT(rt_tick_get)
+RTM_EXPORT(rt_tick_from_millisecond)
+RTM_EXPORT(rt_system_timer_init)
+RTM_EXPORT(rt_system_timer_thread_init)
+RTM_EXPORT(rt_timer_init)
+RTM_EXPORT(rt_timer_detach)
+RTM_EXPORT(rt_timer_create)
+RTM_EXPORT(rt_timer_delete)
+RTM_EXPORT(rt_timer_start)
+RTM_EXPORT(rt_timer_stop)
+RTM_EXPORT(rt_timer_control)
+
+/* 
+ * kservice interface symbol
+ */
+extern int __aeabi_ddiv; 
+extern int __aeabi_dmul;
+extern int __aeabi_i2d;
+extern int __aeabi_uidiv;
+extern int __aeabi_uidivmod;
+extern int __aeabi_d2iz;
+extern int rand;
+
+RTM_EXPORT(rt_kprintf)
+RTM_EXPORT(rt_memcpy)
+RTM_EXPORT(rt_memset)
+RTM_EXPORT(rt_sprintf)
+RTM_EXPORT(__aeabi_ddiv)
+RTM_EXPORT(__aeabi_dmul)
+RTM_EXPORT(__aeabi_i2d)
+RTM_EXPORT(__aeabi_uidiv)
+RTM_EXPORT(__aeabi_uidivmod)
+RTM_EXPORT(__aeabi_d2iz)
+RTM_EXPORT(rand)
+
+#ifdef RT_USING_RTGUI
+/* FIX ME , should be removed from here */
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/view.h>
+#include <rtgui/widgets/workbench.h>
+#include <rtgui/widgets/widget.h>
+
+RTM_EXPORT(rtgui_view_show)
+RTM_EXPORT(rtgui_view_create)
+RTM_EXPORT(rtgui_view_destroy)
+RTM_EXPORT(rtgui_view_event_handler)
+RTM_EXPORT(rtgui_dc_draw_text)
+RTM_EXPORT(rtgui_dc_begin_drawing)
+RTM_EXPORT(rtgui_dc_end_drawing)
+RTM_EXPORT(rtgui_workbench_event_loop)
+RTM_EXPORT(rtgui_workbench_event_handler)
+RTM_EXPORT(rtgui_workbench_add_view)
+RTM_EXPORT(rtgui_workbench_create)
+RTM_EXPORT(rtgui_workbench_destroy)
+RTM_EXPORT(rtgui_workbench_close)
+RTM_EXPORT(rtgui_timer_start)
+RTM_EXPORT(rtgui_timer_create)
+RTM_EXPORT(rtgui_timer_stop)
+RTM_EXPORT(rtgui_widget_focus)
+RTM_EXPORT(rtgui_widget_set_event_handler)
+RTM_EXPORT(rtgui_thread_register)
+RTM_EXPORT(rtgui_thread_deregister)
+
+#endif
+#endif