瀏覽代碼

add module feature

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@604 bbd45198-f89e-11dd-88c7-29a3b14d5316
qiuyiuestc 15 年之前
父節點
當前提交
5211e7ff8f
共有 7 個文件被更改,包括 664 次插入17 次删除
  1. 23 0
      components/thread/module_thread_dynamic.c
  2. 24 0
      include/rtm.h
  3. 28 16
      include/rtthread.h
  4. 6 1
      src/kservice.c
  5. 360 0
      src/module.c
  6. 205 0
      src/module.h
  7. 18 0
      src/thread.c

+ 23 - 0
components/thread/module_thread_dynamic.c

@@ -0,0 +1,23 @@
+#include <rtthread.h>
+
+static void thread_entry(void* parameter)
+{
+	rt_kprintf("thread dynamicly created ok\n");
+	rt_thread_delay(10);
+	rt_kprintf("thread exit\n");
+}
+
+int rtm_main()
+{
+	rt_thread_t tid;
+
+	tid = rt_thread_create("test",
+		thread_entry, RT_NULL,
+		THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
+	if (tid != RT_NULL)
+		rt_thread_startup(tid);
+	else
+		tc_stat(TC_STAT_END | TC_STAT_FAILED);
+
+	return 0;
+}

+ 24 - 0
include/rtm.h

@@ -0,0 +1,24 @@
+#ifndef __RTM_H__
+#define __RTM_H__
+
+#include <rtdef.h>
+
+#ifdef RT_USING_MODULE
+#define RTM_EXPORT(symbol)					 							\
+const char __rtmsym_##symbol##_name[] = #symbol;					 	\
+const struct rt_module_symtab __rtmsym_##symbol SECTION("RTMSymTab")= 	\
+{								\
+	(rt_uint32_t)&symbol,		\
+	__rtmsym_##symbol##_name,	\
+};
+#else
+#define RTM_EXPORT(symbol)	
+#endif
+
+struct rt_module_symtab
+{
+	rt_uint32_t addr;
+	const char* name;
+};
+
+#endif

+ 28 - 16
include/rtthread.h

@@ -14,6 +14,8 @@
  * 2006-08-10     Bernard      add version information
  * 2007-01-28     Bernard      rename RT_OBJECT_Class_Static to RT_Object_Class_Static
  * 2007-03-03     Bernard      clean up the definitions to rtdef.h
+ * 2010-04-11     yi.qiu          add module feature
+
  */
 
 #ifndef __RT_THREAD_H__
@@ -25,6 +27,16 @@
 extern "C" {
 #endif
 
+#if defined(__CC_ARM)
+#ifdef RT_USING_MODULE
+#define RTT_API	__declspec(dllimport)
+#else
+#define RTT_API __declspec(dllexport)
+#endif
+#elif defined(__GNUC__)
+#define RTT_API
+#endif
+
 /**
  * @addtogroup KernelObject
  */
@@ -91,27 +103,27 @@ void rt_timer_timeout_sethook(void (*hook)(struct rt_timer* timer));
 /*
  * thread interface
  */
-rt_err_t rt_thread_init(struct rt_thread* thread,
+RTT_API rt_err_t rt_thread_init(struct rt_thread* thread,
 	const char* name,
 	void (*entry)(void* parameter), void* parameter,
 	void* stack_start, rt_uint32_t stack_size,
 	rt_uint8_t priority, rt_uint32_t tick);
-rt_err_t rt_thread_detach(rt_thread_t thread);
-rt_thread_t rt_thread_create (const char* name,
+RTT_API rt_err_t rt_thread_detach(rt_thread_t thread);
+RTT_API rt_thread_t rt_thread_create (const char* name,
 	void (*entry)(void* parameter), void* parameter,
 	rt_uint32_t stack_size,
 	rt_uint8_t priority, rt_uint32_t tick);
-rt_thread_t rt_thread_self(void);
-rt_thread_t rt_thread_find(char* name);
-rt_err_t rt_thread_startup(rt_thread_t thread);
-rt_err_t rt_thread_delete(rt_thread_t thread);
-
-rt_err_t rt_thread_yield(void);
-rt_err_t rt_thread_delay(rt_tick_t tick);
-rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void* arg);
-rt_err_t rt_thread_suspend(rt_thread_t thread);
-rt_err_t rt_thread_resume(rt_thread_t thread);
-void rt_thread_timeout(void* parameter);
+RTT_API rt_thread_t rt_thread_self(void);
+RTT_API rt_thread_t rt_thread_find(char* name);
+RTT_API rt_err_t rt_thread_startup(rt_thread_t thread);
+RTT_API rt_err_t rt_thread_delete(rt_thread_t thread);
+
+RTT_API rt_err_t rt_thread_yield(void);
+RTT_API rt_err_t rt_thread_delay(rt_tick_t tick);
+RTT_API rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void* arg);
+RTT_API rt_err_t rt_thread_suspend(rt_thread_t thread);
+RTT_API rt_err_t rt_thread_resume(rt_thread_t thread);
+RTT_API void rt_thread_timeout(void* parameter);
 
 /*
  * idle thread interface
@@ -312,8 +324,8 @@ void rt_interrupt_leave(void);
 rt_int32_t rt_sprintf(char *buf ,const char *format,...);
 rt_int32_t rt_vsprintf(char *dest, const char *format, va_list arg_ptr);
 rt_int32_t rt_sprintf(char *buf ,const char *format,...);
-rt_int32_t rt_snprintf(char *buf, rt_size_t size, const char *format, ...);
-
+rt_int32_t rt_snprintf(char *buf, rt_size_t size, const char *format, ...);
+
 rt_device_t rt_console_set_device(const char* name);
 void rt_kprintf(const char *fmt, ...);
 

+ 6 - 1
src/kservice.c

@@ -941,12 +941,12 @@ __weak void rt_hw_console_output(const char* str)
  */
 void rt_kprintf(const char *fmt, ...)
 {
+
 	va_list args;
 	rt_size_t length;
 	static char rt_log_buf[RT_CONSOLEBUF_SIZE];
 
 	va_start(args, fmt);
-
 	length = vsnprintf(rt_log_buf, sizeof(rt_log_buf), fmt, args);
 	if (_console_device == RT_NULL)
 	{
@@ -977,4 +977,9 @@ char *strdup(const char *s) __attribute__((weak, alias("rt_strdup")));
 #endif
 #endif
 
+#ifdef RT_USING_MODULE
+#include <rtm.h>
+/* some buildin kernel symbol */
+RTM_EXPORT(rt_kprintf)
+#endif
 /*@}*/

+ 360 - 0
src/module.c

@@ -0,0 +1,360 @@
+/*
+ * File      : module.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author		Notes
+ * 2010-01-09      Bernard	first version
+ * 2010-04-09      yi.qiu	implement based on first version
+ */
+ 
+#include <rtm.h>
+#include <rtthread.h>
+
+#include "module.h"
+#include "kservice.h"
+
+#ifdef RT_USING_MODULE
+rt_list_t rt_module_symbol_list;
+struct rt_module* rt_current_module;
+struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL, *_rt_module_symtab_end = RT_NULL;
+void rt_system_module_init()
+{
+#ifdef __CC_ARM
+	extern int RTMSymTab$$Base;
+	extern int RTMSymTab$$Limit;
+
+	_rt_module_symtab_begin = (struct rt_module_symtab *)&RTMSymTab$$Base;
+	_rt_module_symtab_end   = (struct rt_module_symtab *)&RTMSymTab$$Limit;
+#elif defined(__GNUC__)
+	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;
+#endif
+
+	rt_list_init(&rt_module_symbol_list);
+}
+
+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 (strcmp(index->name, (const char*)sym_str) == 0)
+			return index->addr;
+	}
+
+	return 0;
+}
+
+#define elf_module 	((Elf32_Ehdr *)module_ptr)
+#define shdr		((Elf32_Shdr *)((rt_uint8_t *)module_ptr + elf_module->e_shoff))
+
+#define IS_PROG(s)		(s.sh_type == SHT_PROGBITS)
+#define IS_NOPROG(s)	(s.sh_type == SHT_NOBITS)
+#define IS_REL(s)		(s.sh_type == SHT_REL)
+#define IS_RELA(s)		(s.sh_type == SHT_RELA)
+#define IS_ALLOC(s)		(s.sh_flags == SHF_ALLOC)
+#define IS_AX(s)		((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_EXECINSTR))
+#define IS_AW(s)		((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_WRITE))
+
+int rt_module_arm_relocate(struct rt_module* module, Elf32_Rel *rel, Elf32_Addr sym_val, rt_uint32_t module_addr)
+{
+	Elf32_Addr *where, tmp;
+	Elf32_Sword addend;
+
+	where = (Elf32_Addr *)((rt_uint8_t*)module->module_space + rel->r_offset - module_addr);
+	switch (ELF32_R_TYPE(rel->r_info))
+	{
+	case R_ARM_NONE:
+		break;
+
+	case R_ARM_ABS32:
+		*where += (Elf32_Addr)sym_val;
+		rt_kprintf("R_ARM_ABS32: %x -> %x\n", where, *where);
+		break;
+
+	case R_ARM_PC24:
+	case R_ARM_PLT32:
+	case R_ARM_CALL:
+	case R_ARM_JUMP24:
+		addend = *where & 0x00ffffff;
+		if (addend & 0x00800000)
+			addend |= 0xff000000;
+		tmp = sym_val - (Elf32_Addr)where + (addend << 2);
+		tmp >>= 2;
+		*where = (*where & 0xff000000) | (tmp & 0x00ffffff);
+		rt_kprintf("R_ARM_PC24: %x -> %x\n", where, *where);
+		break;
+
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+static void rt_module_init_object_container(struct rt_module* module)
+{
+	RT_ASSERT(module != RT_NULL);
+
+	/* init object container - thread */
+	rt_list_init(&(module->module_object[RT_Object_Class_Thread].object_list));
+	module->module_object[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
+	module->module_object[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
+
+#ifdef RT_USING_SEMAPHORE
+	/* init object container - semaphore */
+	rt_list_init(&(module->module_object[RT_Object_Class_Semaphore].object_list));
+	module->module_object[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
+	module->module_object[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
+#endif
+
+#ifdef RT_USING_MUTEX
+	/* init object container - mutex */
+	rt_list_init(&(module->module_object[RT_Object_Class_Mutex].object_list));
+	module->module_object[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
+	module->module_object[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
+#endif
+
+#ifdef RT_USING_FASTEVENT
+	/* init object container - fast event */
+	rt_list_init(&(module->module_object[RT_Object_Class_FastEvent].object_list));
+	module->module_object[RT_Object_Class_FastEvent].object_size = sizeof(struct rt_fast_event);
+	module->module_object[RT_Object_Class_FastEvent].type = RT_Object_Class_FastEvent;
+#endif
+
+#ifdef RT_USING_EVENT
+	/* init object container - event */
+	rt_list_init(&(module->module_object[RT_Object_Class_Event].object_list));
+	module->module_object[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
+	module->module_object[RT_Object_Class_Event].type = RT_Object_Class_Event;
+#endif
+
+#ifdef RT_USING_MAILBOX
+	/* init object container - mailbox */
+	rt_list_init(&(module->module_object[RT_Object_Class_MailBox].object_list));
+	module->module_object[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
+	module->module_object[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
+#endif
+
+#ifdef RT_USING_MESSAGEQUEUE
+	/* init object container - message queue */
+	rt_list_init(&(module->module_object[RT_Object_Class_MessageQueue].object_list));
+	module->module_object[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
+	module->module_object[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
+#endif
+
+#ifdef RT_USING_MEMPOOL
+	/* init object container - memory pool */
+	rt_list_init(&(module->module_object[RT_Object_Class_MemPool].object_list));
+	module->module_object[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
+	module->module_object[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
+#endif
+
+#ifdef RT_USING_DEVICE
+	/* init object container - device */
+	rt_list_init(&(module->module_object[RT_Object_Class_Device].object_list));
+	module->module_object[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
+	module->module_object[RT_Object_Class_Device].type = RT_Object_Class_Device;
+#endif
+
+	/* init object container - timer */
+	rt_list_init(&(module->module_object[RT_Object_Class_Timer].object_list));
+	module->module_object[RT_Object_Class_Timer].object_size = sizeof(struct rt_timer);
+	module->module_object[RT_Object_Class_Timer].type = RT_Object_Class_Timer;
+}
+
+struct rt_module* rt_module_load(void* module_ptr, const rt_uint8_t* name)
+{
+	rt_uint32_t index;
+	rt_uint32_t module_addr = 0, module_size = 0;
+	struct rt_module* module = RT_NULL;
+	rt_uint8_t *ptr, *strtab, *shstrab;
+
+	/* check ELF header */
+	if (rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0 ||
+		elf_module->e_ident[EI_CLASS] != ELFCLASS32)
+		return RT_NULL;
+
+	/* get the ELF image size */
+	for (index = 0; index < elf_module->e_shnum; index++)
+	{
+		/* text */
+		if (IS_PROG(shdr[index]) && IS_AX(shdr[index]))
+		{
+			module_size += shdr[index].sh_size;
+			module_addr = shdr[index].sh_addr;
+		}
+		/* rodata */
+		if (IS_PROG(shdr[index]) && IS_ALLOC(shdr[index]))
+		{
+			module_size += shdr[index].sh_size;
+		}			
+		/* data */
+		if (IS_PROG(shdr[index]) && IS_AW(shdr[index]))
+		{
+			module_size += shdr[index].sh_size;
+		}
+		/* bss */
+		if (IS_NOPROG(shdr[index]) && IS_AW(shdr[index]))
+		{
+			module_size += shdr[index].sh_size;
+		}	
+		
+	}
+
+	/* no text, data and bss on image */
+	if (module_size == 0) return module;
+
+	/* allocate module */
+	module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, (const char*)name);
+	if (module == RT_NULL) return module;
+
+	/* allocate module space */
+	module->module_space = rt_malloc(module_size);
+	if (module->module_space == RT_NULL)
+	{
+		rt_object_delete(&(module->parent));
+		return RT_NULL;
+	}
+
+	/* zero all space */
+	ptr = module->module_space;
+	rt_memset(ptr, 0, module_size);
+
+	/* load text and data section */
+	for (index = 0; index < elf_module->e_shnum; index++)
+	{
+		/* load text and rodata section */
+		if (IS_PROG(shdr[index]) && (IS_AX(shdr[index])||IS_ALLOC(shdr[index])))
+		{
+			rt_memcpy(ptr, (rt_uint8_t*)elf_module + shdr[index].sh_offset, shdr[index].sh_size);
+			ptr += shdr[index].sh_size;
+		}
+
+		/* load data section */
+		if (IS_PROG(shdr[index]) && IS_AW(shdr[index]))
+		{
+			module->module_data = (rt_uint32_t)ptr;
+			rt_memset(ptr, 0, shdr[index].sh_size);
+			ptr += shdr[index].sh_size;
+		}
+	}
+
+	/* set module entry */
+	module->module_entry = (rt_uint8_t*)module->module_space + elf_module->e_entry - module_addr;
+
+	/* handle relocation section */
+	for (index = 0; index < elf_module->e_shnum; index ++)
+	{
+		if (IS_REL(shdr[index]))
+		{
+			rt_uint32_t i, nr_reloc;
+			Elf32_Sym *symtab;
+			Elf32_Rel *rel;
+
+			/* get relocate item */
+			rel = (Elf32_Rel *) ((rt_uint8_t*)module_ptr + shdr[index].sh_offset);
+
+			/* locate .dynsym and .dynstr */
+			symtab =(Elf32_Sym *) ((rt_uint8_t*)module_ptr + shdr[shdr[index].sh_link].sh_offset);
+			strtab = (rt_uint8_t*) module_ptr + shdr[shdr[shdr[index].sh_link].sh_link].sh_offset;
+			shstrab = (rt_uint8_t*) module_ptr + shdr[elf_module->e_shstrndx].sh_offset;
+			nr_reloc = (rt_uint32_t) (shdr[index].sh_size / sizeof(Elf32_Rel));
+
+			/* relocate every items */
+			for (i = 0; i < nr_reloc; i ++)
+			{
+				Elf32_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)];
+				rt_kprintf("relocate symbol: %s\n", strtab + sym->st_name);
+				if (sym->st_shndx != STN_UNDEF)
+				{				
+					if(ELF_ST_TYPE(sym->st_info) == STT_SECTION)
+					{	
+						if (strncmp(shstrab + shdr[sym->st_shndx].sh_name, ELF_RODATA, 8) == 0)
+						{
+							/* relocate rodata section, fix me, module_ptr should be freed */
+							rt_module_arm_relocate(module, rel,
+								(Elf32_Addr)((rt_uint8_t*)module_ptr + shdr[sym->st_shndx].sh_offset),
+								module_addr);
+						}
+						else if(strncmp(shstrab + shdr[sym->st_shndx].sh_name, ELF_BSS, 5) == 0)
+						{
+							/* relocate bss section */
+							rt_module_arm_relocate(module, rel, (Elf32_Addr)ptr, module_addr);
+						}	
+					}
+					else if(ELF_ST_TYPE(sym->st_info) == STT_FUNC )
+					{	
+						/* relocate function */
+						rt_module_arm_relocate(module, rel,
+							(Elf32_Addr)((rt_uint8_t*)module->module_space - module_addr + sym->st_value),
+							module_addr); 
+					}
+					else if(ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
+					{
+						/* relocate object, fix me, module_ptr should be freed */
+						rt_module_arm_relocate(module, rel,
+							(Elf32_Addr)((rt_uint8_t*)module_ptr + shdr[sym->st_shndx].sh_offset + sym->st_value),
+							module_addr); 
+					}
+				}
+				else
+				{
+					rt_kprintf("unresolved relocate symbol: %s\n", strtab + sym->st_name);
+					/* need to resolve symbol in kernel symbol table */
+					Elf32_Addr addr = rt_module_symbol_find(strtab + sym->st_name);
+					if (addr != (Elf32_Addr)RT_NULL)
+						rt_module_arm_relocate(module, rel, addr, module_addr);
+					else rt_kprintf("can't find %s in kernel symbol table\n", strtab + sym->st_name);
+				}
+
+				rel ++;
+			}
+		}
+	}
+
+	/* init module object container */
+	rt_module_init_object_container(module);
+
+	/* create module main thread */
+	module->module_thread = rt_thread_create((const char*)name,
+		module->module_entry, RT_NULL,
+		512, 90, 10);
+	module->module_thread->module_parent = module;
+	rt_thread_startup(module->module_thread);
+
+	return module;
+}
+
+void rt_module_unload(struct rt_module* module)
+{
+	struct rt_object* object;
+
+	/* suspend module main thread */
+	if (module->module_thread->stat == RT_THREAD_READY)
+		rt_thread_suspend(module->module_thread);
+
+	/* delete all module object */
+
+	/* release module memory */
+}
+
+rt_module_t rt_module_find(char* name)
+{
+	struct rt_module* module;
+	module = (struct rt_module*)rt_object_find(RT_Object_Class_Module, name);
+
+	return module;
+}
+
+#endif

+ 205 - 0
src/module.h

@@ -0,0 +1,205 @@
+#ifndef __MODULE_H__
+#define __MODULE_H__
+
+#include <rtdef.h>
+
+typedef rt_uint8_t	Elf_Byte;
+
+typedef rt_uint32_t	Elf32_Addr;	/* Unsigned program address */
+typedef rt_uint32_t	Elf32_Off;	/* Unsigned file offset */
+typedef rt_int32_t	Elf32_Sword;	/* Signed large integer */
+typedef rt_uint32_t	Elf32_Word;	/* Unsigned large integer */
+typedef rt_uint16_t	Elf32_Half;	/* Unsigned medium integer */
+
+/* e_ident[] magic number */
+#define	ELFMAG0		0x7f		/* e_ident[EI_MAG0] */
+#define	ELFMAG1		'E'			/* e_ident[EI_MAG1] */
+#define	ELFMAG2		'L'			/* e_ident[EI_MAG2] */
+#define	ELFMAG3		'F'			/* e_ident[EI_MAG3] */
+#define	ELFMAG		"\177ELF"	/* magic */
+#define	SELFMAG		4			/* size of magic */
+
+#define EI_CLASS	4		/* file class */
+#define EI_NIDENT	16			/* Size of e_ident[] */
+
+/* e_ident[] file class */
+#define	ELFCLASSNONE	0		/* invalid */
+#define	ELFCLASS32		1		/* 32-bit objs */
+#define	ELFCLASS64		2		/* 64-bit objs */
+#define	ELFCLASSNUM		3		/* number of classes */
+
+/* e_ident[] data encoding */
+#define ELFDATANONE		0		/* invalid */
+#define ELFDATA2LSB		1		/* Little-Endian */
+#define ELFDATA2MSB		2		/* Big-Endian */
+#define ELFDATANUM		3		/* number of data encode defines */
+
+/* e_ident */
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+                      (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+                      (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+                      (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+/* ELF Header */
+typedef struct elfhdr {
+	unsigned char	e_ident[EI_NIDENT]; /* ELF Identification */
+	Elf32_Half	e_type;		/* object file type */
+	Elf32_Half	e_machine;	/* machine */
+	Elf32_Word	e_version;	/* object file version */
+	Elf32_Addr	e_entry;	/* virtual entry point */
+	Elf32_Off	e_phoff;	/* program header table offset */
+	Elf32_Off	e_shoff;	/* section header table offset */
+	Elf32_Word	e_flags;	/* processor-specific flags */
+	Elf32_Half	e_ehsize;	/* ELF header size */
+	Elf32_Half	e_phentsize;	/* program header entry size */
+	Elf32_Half	e_phnum;	/* number of program header entries */
+	Elf32_Half	e_shentsize;	/* section header entry size */
+	Elf32_Half	e_shnum;	/* number of section header entries */
+	Elf32_Half	e_shstrndx;	/* section header table's "section
+					   header string table" entry offset */
+} Elf32_Ehdr;
+
+/* Section Header */
+typedef struct {
+	Elf32_Word	sh_name;	/* name - index into section header
+					   string table section */
+	Elf32_Word	sh_type;	/* type */
+	Elf32_Word	sh_flags;	/* flags */
+	Elf32_Addr	sh_addr;	/* address */
+	Elf32_Off	sh_offset;	/* file offset */
+	Elf32_Word	sh_size;	/* section size */
+	Elf32_Word	sh_link;	/* section header table index link */
+	Elf32_Word	sh_info;	/* extra information */
+	Elf32_Word	sh_addralign;	/* address alignment */
+	Elf32_Word	sh_entsize;	/* section entry size */
+} Elf32_Shdr;
+
+/* Section names */
+#define ELF_BSS         ".bss"		/* uninitialized data */
+#define ELF_DATA        ".data"		/* initialized data */
+#define ELF_DEBUG       ".debug"	/* debug */
+#define ELF_DYNAMIC     ".dynamic"	/* dynamic linking information */
+#define ELF_DYNSTR      ".dynstr"	/* dynamic string table */
+#define ELF_DYNSYM      ".dynsym"	/* dynamic symbol table */
+#define ELF_FINI        ".fini"		/* termination code */
+#define ELF_GOT         ".got"		/* global offset table */
+#define ELF_HASH        ".hash"		/* symbol hash table */
+#define ELF_INIT        ".init"		/* initialization code */
+#define ELF_REL_DATA    ".rel.data"	/* relocation data */
+#define ELF_REL_FINI    ".rel.fini"	/* relocation termination code */
+#define ELF_REL_INIT    ".rel.init"	/* relocation initialization code */
+#define ELF_REL_DYN     ".rel.dyn"	/* relocaltion dynamic link info */
+#define ELF_REL_RODATA  ".rel.rodata"	/* relocation read-only data */
+#define ELF_REL_TEXT    ".rel.text"	/* relocation code */
+#define ELF_RODATA      ".rodata"	/* read-only data */
+#define ELF_SHSTRTAB    ".shstrtab"	/* section header string table */
+#define ELF_STRTAB      ".strtab"	/* string table */
+#define ELF_SYMTAB      ".symtab"	/* symbol table */
+#define ELF_TEXT        ".text"		/* code */
+
+/* Symbol Table Entry */
+typedef struct elf32_sym {
+	Elf32_Word	st_name;	/* name - index into string table */
+	Elf32_Addr	st_value;	/* symbol value */
+	Elf32_Word	st_size;	/* symbol size */
+	unsigned char	st_info;	/* type and binding */
+	unsigned char	st_other;	/* 0 - no defined meaning */
+	Elf32_Half	st_shndx;	/* section header index */
+} Elf32_Sym;
+
+#define	STB_LOCAL	0		/* BIND */
+#define	STB_GLOBAL	1
+#define	STB_WEAK	2
+#define	STB_NUM	3
+ 
+#define	STB_LOPROC	13		/* processor specific range */
+#define	STB_HIPROC	15
+
+#define	STT_NOTYPE	0		/* symbol type is unspecified */
+#define	STT_OBJECT	1		/* data object */
+#define	STT_FUNC	2		/* code object */
+#define	STT_SECTION	3	/* symbol identifies an ELF section */
+#define	STT_FILE	4		/* symbol's name is file name */
+#define	STT_COMMON	5	/* common data object */
+#define	STT_TLS		6		/* thread-local data object */
+#define	STT_NUM	7		/* # defined types in generic range */
+#define	STT_LOOS	10		/* OS specific range */
+#define	STT_HIOS	12
+#define	STT_LOPROC	13		/* processor specific range */
+#define	STT_HIPROC	15
+    
+
+#define	ELF_ST_BIND(info)			((info) >> 4)
+#define	ELF_ST_TYPE(info)			((info) & 0xf)
+#define	ELF_ST_INFO(bind, type)		(((bind)<<4)+((type)&0xf))	
+
+/* Relocation entry with implicit addend */
+typedef struct {
+	Elf32_Addr	r_offset;	/* offset of relocation */
+	Elf32_Word	r_info;		/* symbol table index and type */
+} Elf32_Rel;
+
+/* Relocation entry with explicit addend */
+typedef struct {
+	Elf32_Addr	r_offset;	/* offset of relocation */
+	Elf32_Word	r_info;		/* symbol table index and type */
+	Elf32_Sword	r_addend;
+} Elf32_Rela;
+
+/* Extract relocation info - r_info */
+#define ELF32_R_SYM(i)		((i) >> 8)
+#define ELF32_R_TYPE(i)		((unsigned char) (i))
+#define ELF32_R_INFO(s,t) 	(((s) << 8) + (unsigned char)(t))
+
+/*
+ * Relocation type for arm
+ */
+#define	R_ARM_NONE	0
+#define	R_ARM_PC24	1
+#define	R_ARM_ABS32	2
+#define	R_ARM_PLT32	27
+#define	R_ARM_CALL	28
+#define R_ARM_JUMP24	29
+
+/* Program Header */
+typedef struct {
+	Elf32_Word	p_type;		/* segment type */
+	Elf32_Off	p_offset;	/* segment offset */
+	Elf32_Addr	p_vaddr;	/* virtual address of segment */
+	Elf32_Addr	p_paddr;	/* physical address - ignored? */
+	Elf32_Word	p_filesz;	/* number of bytes in file for seg. */
+	Elf32_Word	p_memsz;	/* number of bytes in mem. for seg. */
+	Elf32_Word	p_flags;	/* flags */
+	Elf32_Word	p_align;	/* memory alignment */
+} Elf32_Phdr;
+
+/* sh_type */
+#define SHT_NULL	0		/* inactive */
+#define SHT_PROGBITS	1		/* program defined information */
+#define SHT_SYMTAB	2		/* symbol table section */
+#define SHT_STRTAB	3		/* string table section */
+#define SHT_RELA	4		/* relocation section with addends*/
+#define SHT_HASH	5		/* symbol hash table section */
+#define SHT_DYNAMIC	6		/* dynamic section */
+#define SHT_NOTE	7		/* note section */
+#define SHT_NOBITS	8		/* no space section */
+#define SHT_REL		9		/* relation section without addends */
+#define SHT_SHLIB	10		/* reserved - purpose unknown */
+#define SHT_DYNSYM	11		/* dynamic symbol table section */
+#define SHT_NUM		12		/* number of section types */
+#define SHT_LOPROC	0x70000000	/* reserved range for processor */
+#define SHT_HIPROC	0x7fffffff	/*  specific section header types */
+#define SHT_LOUSER	0x80000000	/* reserved range for application */
+#define SHT_HIUSER	0xffffffff	/*  specific indexes */
+
+/* Section Attribute Flags - sh_flags */
+#define SHF_WRITE	0x1		/* Writable */
+#define SHF_ALLOC	0x2		/* occupies memory */
+#define SHF_EXECINSTR	0x4		/* executable */
+#define SHF_MASKPROC	0xf0000000	/* reserved bits for processor */
+					/*  specific section attributes */
+
+/* Symbol table index */
+#define STN_UNDEF	0		/* undefined */
+
+#endif

+ 18 - 0
src/thread.c

@@ -19,6 +19,7 @@
  * 2006-09-03     Bernard      implement rt_thread_detach
  * 2008-02-16     Bernard      fix the rt_thread_timeout bug
  * 2010-03-21     Bernard      change the errno of rt_thread_delay/sleep to RT_EOK.
+ * 2010-04-11     yi.qiu          add module feature
  */
 
 #include <rtthread.h>
@@ -627,4 +628,21 @@ rt_thread_t rt_thread_find(char* name)
 	return thread;
 }
 
+#ifdef RT_USING_MODULE
+#include <rtm.h>
+/* some buildin kernel 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)
+#endif
 /*@}*/