[Kernel] More better support for module.
This commit is contained in:
parent
db73a31ec8
commit
abd19b8dd7
|
@ -892,7 +892,8 @@ enum
|
||||||
RTGRAPHIC_PIXEL_FORMAT_BGR565 = RTGRAPHIC_PIXEL_FORMAT_RGB565P,
|
RTGRAPHIC_PIXEL_FORMAT_BGR565 = RTGRAPHIC_PIXEL_FORMAT_RGB565P,
|
||||||
RTGRAPHIC_PIXEL_FORMAT_RGB666,
|
RTGRAPHIC_PIXEL_FORMAT_RGB666,
|
||||||
RTGRAPHIC_PIXEL_FORMAT_RGB888,
|
RTGRAPHIC_PIXEL_FORMAT_RGB888,
|
||||||
RTGRAPHIC_PIXEL_FORMAT_ARGB888
|
RTGRAPHIC_PIXEL_FORMAT_ARGB888,
|
||||||
|
RTGRAPHIC_PIXEL_FORMAT_ABGR888,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -965,6 +966,8 @@ struct rt_module
|
||||||
{
|
{
|
||||||
struct rt_object parent; /**< inherit from object */
|
struct rt_object parent; /**< inherit from object */
|
||||||
|
|
||||||
|
rt_uint32_t vstart_addr; /**< VMA base address for the
|
||||||
|
first LOAD segment. */
|
||||||
rt_uint8_t *module_space; /**< module memory space */
|
rt_uint8_t *module_space; /**< module memory space */
|
||||||
|
|
||||||
void *module_entry; /**< the entry address of module */
|
void *module_entry; /**< the entry address of module */
|
||||||
|
|
329
src/module.c
329
src/module.c
|
@ -33,6 +33,10 @@
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <rtm.h>
|
#include <rtm.h>
|
||||||
|
|
||||||
|
#ifdef RT_USING_FINSH
|
||||||
|
#include <finsh.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RT_USING_MODULE
|
#ifdef RT_USING_MODULE
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
|
|
||||||
|
@ -48,6 +52,18 @@
|
||||||
#define IS_AX(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_EXECINSTR))
|
#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))
|
#define IS_AW(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_WRITE))
|
||||||
|
|
||||||
|
#ifdef RT_USING_MODULE_STKSZ
|
||||||
|
#undef RT_USING_MODULE_STKSZ
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RT_USING_MODULE_STKSZ
|
||||||
|
#define RT_USING_MODULE_STKSZ (4096 * 2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RT_USING_MODULE_PRIO
|
||||||
|
#define RT_USING_MODULE_PRIO (RT_THREAD_PRIORITY_MAX - 2)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RT_USING_SLAB
|
#ifdef RT_USING_SLAB
|
||||||
#define PAGE_COUNT_MAX 256
|
#define PAGE_COUNT_MAX 256
|
||||||
|
|
||||||
|
@ -75,6 +91,10 @@ static struct rt_semaphore mod_sem;
|
||||||
static struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL;
|
static struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL;
|
||||||
static struct rt_module_symtab *_rt_module_symtab_end = RT_NULL;
|
static struct rt_module_symtab *_rt_module_symtab_end = RT_NULL;
|
||||||
|
|
||||||
|
#if defined(__IAR_SYSTEMS_ICC__) /* for IAR compiler */
|
||||||
|
#pragma section="RTMSymTab"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup SystemInit
|
* @ingroup SystemInit
|
||||||
*
|
*
|
||||||
|
@ -94,6 +114,9 @@ int rt_system_module_init(void)
|
||||||
|
|
||||||
_rt_module_symtab_begin = (struct rt_module_symtab *)&RTMSymTab$$Base;
|
_rt_module_symtab_begin = (struct rt_module_symtab *)&RTMSymTab$$Base;
|
||||||
_rt_module_symtab_end = (struct rt_module_symtab *)&RTMSymTab$$Limit;
|
_rt_module_symtab_end = (struct rt_module_symtab *)&RTMSymTab$$Limit;
|
||||||
|
#elif defined (__IAR_SYSTEMS_ICC__)
|
||||||
|
_rt_module_symtab_begin = __section_begin("RTMSymTab");
|
||||||
|
_rt_module_symtab_end = __section_begin("RTMSymTab");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RT_USING_SLAB
|
#ifdef RT_USING_SLAB
|
||||||
|
@ -104,6 +127,25 @@ int rt_system_module_init(void)
|
||||||
}
|
}
|
||||||
INIT_COMPONENT_EXPORT(rt_system_module_init);
|
INIT_COMPONENT_EXPORT(rt_system_module_init);
|
||||||
|
|
||||||
|
#ifdef RT_USING_FINSH
|
||||||
|
void list_symbol(void)
|
||||||
|
{
|
||||||
|
/* find in kernel symbol table */
|
||||||
|
struct rt_module_symtab *index;
|
||||||
|
|
||||||
|
for (index = _rt_module_symtab_begin;
|
||||||
|
index != _rt_module_symtab_end;
|
||||||
|
index ++)
|
||||||
|
{
|
||||||
|
rt_kprintf("%s\n", index->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
FINSH_FUNCTION_EXPORT(list_symbol, list symbol for module);
|
||||||
|
MSH_CMD_EXPORT(list_symbol, list symbol for module);
|
||||||
|
#endif
|
||||||
|
|
||||||
static rt_uint32_t rt_module_symbol_find(const char *sym_str)
|
static rt_uint32_t rt_module_symbol_find(const char *sym_str)
|
||||||
{
|
{
|
||||||
/* find in kernel symbol table */
|
/* find in kernel symbol table */
|
||||||
|
@ -145,7 +187,9 @@ static int rt_module_arm_relocate(struct rt_module *module,
|
||||||
Elf32_Sword addend, offset;
|
Elf32_Sword addend, offset;
|
||||||
rt_uint32_t upper, lower, sign, j1, j2;
|
rt_uint32_t upper, lower, sign, j1, j2;
|
||||||
|
|
||||||
where = (Elf32_Addr *)((rt_uint8_t *)module->module_space + rel->r_offset);
|
where = (Elf32_Addr *)((rt_uint8_t *)module->module_space
|
||||||
|
+ rel->r_offset
|
||||||
|
- module->vstart_addr);
|
||||||
switch (ELF32_R_TYPE(rel->r_info))
|
switch (ELF32_R_TYPE(rel->r_info))
|
||||||
{
|
{
|
||||||
case R_ARM_NONE:
|
case R_ARM_NONE:
|
||||||
|
@ -351,10 +395,11 @@ void rt_module_unload_sethook(void (*hook)(rt_module_t module))
|
||||||
static struct rt_module *_load_shared_object(const char *name,
|
static struct rt_module *_load_shared_object(const char *name,
|
||||||
void *module_ptr)
|
void *module_ptr)
|
||||||
{
|
{
|
||||||
rt_uint8_t *ptr = RT_NULL;
|
|
||||||
rt_module_t module = RT_NULL;
|
rt_module_t module = RT_NULL;
|
||||||
rt_bool_t linked = RT_FALSE;
|
rt_bool_t linked = RT_FALSE;
|
||||||
rt_uint32_t index, module_size = 0;
|
rt_uint32_t index, module_size = 0;
|
||||||
|
Elf32_Addr vstart_addr, vend_addr;
|
||||||
|
rt_bool_t has_vstart;
|
||||||
|
|
||||||
RT_ASSERT(module_ptr != RT_NULL);
|
RT_ASSERT(module_ptr != RT_NULL);
|
||||||
|
|
||||||
|
@ -365,11 +410,61 @@ static struct rt_module *_load_shared_object(const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the ELF image size */
|
/* get the ELF image size */
|
||||||
|
has_vstart = RT_FALSE;
|
||||||
|
vstart_addr = vend_addr = RT_NULL;
|
||||||
for (index = 0; index < elf_module->e_phnum; index++)
|
for (index = 0; index < elf_module->e_phnum; index++)
|
||||||
{
|
{
|
||||||
if (phdr[index].p_type == PT_LOAD)
|
if (phdr[index].p_type != PT_LOAD)
|
||||||
module_size += phdr[index].p_memsz;
|
continue;
|
||||||
|
|
||||||
|
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("LOAD segment: %d, 0x%p, 0x%08x\n",
|
||||||
|
index, phdr[index].p_vaddr, phdr[index].p_memsz));
|
||||||
|
|
||||||
|
if (phdr[index].p_memsz < phdr[index].p_filesz)
|
||||||
|
{
|
||||||
|
rt_kprintf("invalid elf: segment %d: p_memsz: %d, p_filesz: %d\n",
|
||||||
|
index, phdr[index].p_memsz, phdr[index].p_filesz);
|
||||||
|
return RT_NULL;
|
||||||
}
|
}
|
||||||
|
if (!has_vstart)
|
||||||
|
{
|
||||||
|
vstart_addr = phdr[index].p_vaddr;
|
||||||
|
vend_addr = phdr[index].p_vaddr + phdr[index].p_memsz;
|
||||||
|
has_vstart = RT_TRUE;
|
||||||
|
if (vend_addr < vstart_addr)
|
||||||
|
{
|
||||||
|
rt_kprintf("invalid elf: segment %d: p_vaddr: %d, p_memsz: %d\n",
|
||||||
|
index, phdr[index].p_vaddr, phdr[index].p_memsz);
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (phdr[index].p_vaddr < vend_addr)
|
||||||
|
{
|
||||||
|
rt_kprintf("invalid elf: segment should be sorted and not overlapped\n");
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
if (phdr[index].p_vaddr > vend_addr + 16)
|
||||||
|
{
|
||||||
|
/* There should not be too much padding in the object files. */
|
||||||
|
rt_kprintf("warning: too much padding before segment %d\n", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
vend_addr = phdr[index].p_vaddr + phdr[index].p_memsz;
|
||||||
|
if (vend_addr < phdr[index].p_vaddr)
|
||||||
|
{
|
||||||
|
rt_kprintf("invalid elf: "
|
||||||
|
"segment %d address overflow\n", index);
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module_size = vend_addr - vstart_addr;
|
||||||
|
|
||||||
|
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("module size: %d, vstart_addr: 0x%p\n",
|
||||||
|
module_size, vstart_addr));
|
||||||
|
|
||||||
if (module_size == 0)
|
if (module_size == 0)
|
||||||
{
|
{
|
||||||
|
@ -384,6 +479,8 @@ static struct rt_module *_load_shared_object(const char *name,
|
||||||
if (!module)
|
if (!module)
|
||||||
return RT_NULL;
|
return RT_NULL;
|
||||||
|
|
||||||
|
module->vstart_addr = vstart_addr;
|
||||||
|
|
||||||
module->nref = 0;
|
module->nref = 0;
|
||||||
|
|
||||||
/* allocate module space */
|
/* allocate module space */
|
||||||
|
@ -397,21 +494,21 @@ static struct rt_module *_load_shared_object(const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* zero all space */
|
/* zero all space */
|
||||||
ptr = module->module_space;
|
rt_memset(module->module_space, 0, module_size);
|
||||||
rt_memset(ptr, 0, module_size);
|
|
||||||
|
|
||||||
for (index = 0; index < elf_module->e_phnum; index++)
|
for (index = 0; index < elf_module->e_phnum; index++)
|
||||||
{
|
{
|
||||||
if (phdr[index].p_type == PT_LOAD)
|
if (phdr[index].p_type == PT_LOAD)
|
||||||
{
|
{
|
||||||
rt_memcpy(ptr + phdr[index].p_paddr,
|
rt_memcpy(module->module_space + phdr[index].p_vaddr - vstart_addr,
|
||||||
(rt_uint8_t *)elf_module + phdr[index].p_offset,
|
(rt_uint8_t *)elf_module + phdr[index].p_offset,
|
||||||
phdr[index].p_filesz);
|
phdr[index].p_filesz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set module entry */
|
/* set module entry */
|
||||||
module->module_entry = module->module_space + elf_module->e_entry;
|
module->module_entry = module->module_space
|
||||||
|
+ elf_module->e_entry - vstart_addr;
|
||||||
|
|
||||||
/* handle relocation section */
|
/* handle relocation section */
|
||||||
for (index = 0; index < elf_module->e_shnum; index ++)
|
for (index = 0; index < elf_module->e_shnum; index ++)
|
||||||
|
@ -448,7 +545,9 @@ static struct rt_module *_load_shared_object(const char *name,
|
||||||
(ELF_ST_BIND(sym->st_info) == STB_LOCAL))
|
(ELF_ST_BIND(sym->st_info) == STB_LOCAL))
|
||||||
{
|
{
|
||||||
rt_module_arm_relocate(module, rel,
|
rt_module_arm_relocate(module, rel,
|
||||||
(Elf32_Addr)(module->module_space + sym->st_value));
|
(Elf32_Addr)(module->module_space
|
||||||
|
+ sym->st_value
|
||||||
|
- vstart_addr));
|
||||||
}
|
}
|
||||||
else if (!linked)
|
else if (!linked)
|
||||||
{
|
{
|
||||||
|
@ -578,6 +677,8 @@ static struct rt_module* _load_relocated_object(const char *name,
|
||||||
if (module == RT_NULL)
|
if (module == RT_NULL)
|
||||||
return RT_NULL;
|
return RT_NULL;
|
||||||
|
|
||||||
|
module->vstart_addr = 0;
|
||||||
|
|
||||||
/* allocate module space */
|
/* allocate module space */
|
||||||
module->module_space = rt_malloc(module_size);
|
module->module_space = rt_malloc(module_size);
|
||||||
if (module->module_space == RT_NULL)
|
if (module->module_space == RT_NULL)
|
||||||
|
@ -710,8 +811,11 @@ static struct rt_module* _load_relocated_object(const char *name,
|
||||||
else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
|
else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
|
||||||
{
|
{
|
||||||
/* relocate function */
|
/* relocate function */
|
||||||
rt_module_arm_relocate(module, rel, (Elf32_Addr)((rt_uint8_t *)
|
rt_module_arm_relocate(module, rel,
|
||||||
module->module_space - module_addr + sym->st_value));
|
(Elf32_Addr)((rt_uint8_t *)
|
||||||
|
module->module_space
|
||||||
|
- module_addr
|
||||||
|
+ sym->st_value));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -736,8 +840,11 @@ static struct rt_module* _load_relocated_object(const char *name,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt_module_arm_relocate(module, rel, (Elf32_Addr)((rt_uint8_t*)
|
rt_module_arm_relocate(module, rel,
|
||||||
module->module_space - module_addr + sym->st_value));
|
(Elf32_Addr)((rt_uint8_t*)
|
||||||
|
module->module_space
|
||||||
|
- module_addr
|
||||||
|
+ sym->st_value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rel ++;
|
rel ++;
|
||||||
|
@ -747,110 +854,6 @@ static struct rt_module* _load_relocated_object(const char *name,
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will load a module from memory and create a thread for it
|
|
||||||
*
|
|
||||||
* @param name the name of module, which shall be unique
|
|
||||||
* @param module_ptr the memory address of module image
|
|
||||||
*
|
|
||||||
* @return the module object
|
|
||||||
*/
|
|
||||||
rt_module_t rt_module_load(const char *name, void *module_ptr)
|
|
||||||
{
|
|
||||||
rt_module_t module;
|
|
||||||
|
|
||||||
RT_DEBUG_NOT_IN_INTERRUPT;
|
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_load: %s ,", name));
|
|
||||||
|
|
||||||
/* check ELF header */
|
|
||||||
if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
|
|
||||||
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: ELF class error\n");
|
|
||||||
|
|
||||||
return RT_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elf_module->e_type == ET_REL)
|
|
||||||
{
|
|
||||||
module = _load_relocated_object(name, module_ptr);
|
|
||||||
}
|
|
||||||
else if (elf_module->e_type == ET_DYN)
|
|
||||||
{
|
|
||||||
module = _load_shared_object(name, module_ptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rt_kprintf("Module: unsupported elf type\n");
|
|
||||||
|
|
||||||
return RT_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (module == RT_NULL)
|
|
||||||
return RT_NULL;
|
|
||||||
|
|
||||||
/* init module object container */
|
|
||||||
rt_module_init_object_container(module);
|
|
||||||
|
|
||||||
/* initialize an empty command */
|
|
||||||
module->module_cmd_line = RT_NULL;
|
|
||||||
module->module_cmd_size = 0;
|
|
||||||
|
|
||||||
/* increase module reference count */
|
|
||||||
module->nref ++;
|
|
||||||
|
|
||||||
if (elf_module->e_entry != 0)
|
|
||||||
{
|
|
||||||
#ifdef RT_USING_SLAB
|
|
||||||
/* init module memory allocator */
|
|
||||||
module->mem_list = RT_NULL;
|
|
||||||
|
|
||||||
/* create page array */
|
|
||||||
module->page_array =
|
|
||||||
(void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info));
|
|
||||||
module->page_cnt = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* create module thread */
|
|
||||||
module->module_thread = rt_thread_create(name,
|
|
||||||
(void(*)(void *))module->module_entry, RT_NULL,
|
|
||||||
2048, RT_THREAD_PRIORITY_MAX - 2, 10);
|
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("thread entry 0x%x\n",
|
|
||||||
module->module_entry));
|
|
||||||
|
|
||||||
/* set module id */
|
|
||||||
module->module_thread->module_id = (void *)module;
|
|
||||||
module->parent.flag = RT_MODULE_FLAG_WITHENTRY;
|
|
||||||
|
|
||||||
/* startup module thread */
|
|
||||||
rt_thread_startup(module->module_thread);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* without entry point */
|
|
||||||
module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RT_USING_HOOK
|
|
||||||
if (rt_module_load_hook != RT_NULL)
|
|
||||||
{
|
|
||||||
rt_module_load_hook(module);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return module;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define RT_MODULE_ARG_MAX 8
|
#define RT_MODULE_ARG_MAX 8
|
||||||
static int _rt_module_split_arg(char* cmd, rt_size_t length, char* argv[])
|
static int _rt_module_split_arg(char* cmd, rt_size_t length, char* argv[])
|
||||||
{
|
{
|
||||||
|
@ -890,6 +893,7 @@ static int _rt_module_split_arg(char* cmd, rt_size_t length, char* argv[])
|
||||||
|
|
||||||
return argc;
|
return argc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* module main thread entry */
|
/* module main thread entry */
|
||||||
static void module_main_entry(void* parameter)
|
static void module_main_entry(void* parameter)
|
||||||
{
|
{
|
||||||
|
@ -898,12 +902,33 @@ static void module_main_entry(void* parameter)
|
||||||
typedef int (*main_func_t)(int argc, char** argv);
|
typedef int (*main_func_t)(int argc, char** argv);
|
||||||
|
|
||||||
rt_module_t module = (rt_module_t) parameter;
|
rt_module_t module = (rt_module_t) parameter;
|
||||||
if (module == RT_NULL || module->module_cmd_line == RT_NULL) return;
|
if (module == RT_NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (module->module_cmd_line == RT_NULL && module->module_cmd_size != 0)
|
||||||
|
/* malloc for module_cmd_line failed. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* FIXME: we should run some C++ initialize code before jump into the
|
||||||
|
* entry. */
|
||||||
|
|
||||||
|
if (module->module_cmd_line == RT_NULL)
|
||||||
|
{
|
||||||
|
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("run bare entry: 0x%p\n",
|
||||||
|
module->module_entry));
|
||||||
|
((main_func_t)module->module_entry)(0, RT_NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rt_memset(argv, 0x00, sizeof(argv));
|
rt_memset(argv, 0x00, sizeof(argv));
|
||||||
argc = _rt_module_split_arg((char*)module->module_cmd_line, module->module_cmd_size, argv);
|
argc = _rt_module_split_arg((char*)module->module_cmd_line,
|
||||||
if (argc == 0) return ;
|
module->module_cmd_size, argv);
|
||||||
|
if (argc == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("run main entry: 0x%p with %s\n",
|
||||||
|
module->module_entry,
|
||||||
|
module->module_cmd_line));
|
||||||
/* do the main function */
|
/* do the main function */
|
||||||
((main_func_t)module->module_entry)(argc, argv);
|
((main_func_t)module->module_entry)(argc, argv);
|
||||||
return;
|
return;
|
||||||
|
@ -920,13 +945,16 @@ static void module_main_entry(void* parameter)
|
||||||
*
|
*
|
||||||
* @return the module object
|
* @return the module object
|
||||||
*/
|
*/
|
||||||
rt_module_t rt_module_do_main(const char *name, void *module_ptr, const char* cmd_line, int line_size)
|
rt_module_t rt_module_do_main(const char *name,
|
||||||
|
void *module_ptr,
|
||||||
|
const char* cmd_line,
|
||||||
|
int line_size)
|
||||||
{
|
{
|
||||||
rt_module_t module;
|
rt_module_t module;
|
||||||
|
|
||||||
RT_DEBUG_NOT_IN_INTERRUPT;
|
RT_DEBUG_NOT_IN_INTERRUPT;
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_load: %s ,", name));
|
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_load: %s\n", name));
|
||||||
|
|
||||||
/* check ELF header */
|
/* check ELF header */
|
||||||
if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
|
if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
|
||||||
|
@ -941,6 +969,7 @@ rt_module_t rt_module_do_main(const char *name, void *module_ptr, const char* cm
|
||||||
if (elf_module->e_ident[EI_CLASS] != ELFCLASS32)
|
if (elf_module->e_ident[EI_CLASS] != ELFCLASS32)
|
||||||
{
|
{
|
||||||
rt_kprintf("Module: ELF class error\n");
|
rt_kprintf("Module: ELF class error\n");
|
||||||
|
|
||||||
return RT_NULL;
|
return RT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,7 +983,8 @@ rt_module_t rt_module_do_main(const char *name, void *module_ptr, const char* cm
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt_kprintf("Module: unsupported excutable program\n");
|
rt_kprintf("Module: unsupported elf type\n");
|
||||||
|
|
||||||
return RT_NULL;
|
return RT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -964,6 +994,24 @@ rt_module_t rt_module_do_main(const char *name, void *module_ptr, const char* cm
|
||||||
/* init module object container */
|
/* init module object container */
|
||||||
rt_module_init_object_container(module);
|
rt_module_init_object_container(module);
|
||||||
|
|
||||||
|
if (line_size && cmd_line)
|
||||||
|
{
|
||||||
|
/* set module argument */
|
||||||
|
module->module_cmd_line = (rt_uint8_t*)rt_malloc(line_size + 1);
|
||||||
|
if (module->module_cmd_line)
|
||||||
|
{
|
||||||
|
rt_memcpy(module->module_cmd_line, cmd_line, line_size);
|
||||||
|
module->module_cmd_line[line_size] = '\0';
|
||||||
|
}
|
||||||
|
module->module_cmd_size = line_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* initialize an empty command */
|
||||||
|
module->module_cmd_line = RT_NULL;
|
||||||
|
module->module_cmd_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* increase module reference count */
|
/* increase module reference count */
|
||||||
module->nref ++;
|
module->nref ++;
|
||||||
|
|
||||||
|
@ -979,22 +1027,20 @@ rt_module_t rt_module_do_main(const char *name, void *module_ptr, const char* cm
|
||||||
module->page_cnt = 0;
|
module->page_cnt = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* set module argument */
|
|
||||||
module->module_cmd_line = (rt_uint8_t*)rt_malloc(line_size + 1);
|
|
||||||
rt_memcpy(module->module_cmd_line, cmd_line, line_size);
|
|
||||||
module->module_cmd_line[line_size] = '\0';
|
|
||||||
module->module_cmd_size = line_size;
|
|
||||||
|
|
||||||
/* create module thread */
|
/* create module thread */
|
||||||
module->module_thread = rt_thread_create(name,
|
module->module_thread = rt_thread_create(name,
|
||||||
module_main_entry, module,
|
module_main_entry, module,
|
||||||
2048, RT_THREAD_PRIORITY_MAX - 2, 10);
|
RT_USING_MODULE_STKSZ,
|
||||||
|
RT_USING_MODULE_PRIO, 10);
|
||||||
|
|
||||||
|
RT_DEBUG_LOG(RT_DEBUG_MODULE, ("thread entry 0x%x\n",
|
||||||
|
module->module_entry));
|
||||||
|
|
||||||
/* set module id */
|
/* set module id */
|
||||||
module->module_thread->module_id = (void *)module;
|
module->module_thread->module_id = (void *)module;
|
||||||
module->parent.flag = RT_MODULE_FLAG_WITHENTRY;
|
module->parent.flag = RT_MODULE_FLAG_WITHENTRY;
|
||||||
|
|
||||||
/* startup main thread */
|
/* startup module thread */
|
||||||
rt_thread_startup(module->module_thread);
|
rt_thread_startup(module->module_thread);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1013,6 +1059,19 @@ rt_module_t rt_module_do_main(const char *name, void *module_ptr, const char* cm
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will load a module from memory and create a thread for it
|
||||||
|
*
|
||||||
|
* @param name the name of module, which shall be unique
|
||||||
|
* @param module_ptr the memory address of module image
|
||||||
|
*
|
||||||
|
* @return the module object
|
||||||
|
*/
|
||||||
|
rt_module_t rt_module_load(const char *name, void *module_ptr)
|
||||||
|
{
|
||||||
|
return rt_module_do_main(name, module_ptr, RT_NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_DFS
|
#ifdef RT_USING_DFS
|
||||||
#include <dfs_posix.h>
|
#include <dfs_posix.h>
|
||||||
|
|
||||||
|
@ -1224,7 +1283,7 @@ rt_err_t rt_module_destroy(rt_module_t module)
|
||||||
{
|
{
|
||||||
#ifdef RT_USING_SEMAPHORE
|
#ifdef RT_USING_SEMAPHORE
|
||||||
/* delete semaphores */
|
/* delete semaphores */
|
||||||
list = &module->module_object[RT_Object_Class_Thread].object_list;
|
list = &module->module_object[RT_Object_Class_Semaphore].object_list;
|
||||||
while (list->next != list)
|
while (list->next != list)
|
||||||
{
|
{
|
||||||
object = rt_list_entry(list->next, struct rt_object, list);
|
object = rt_list_entry(list->next, struct rt_object, list);
|
||||||
|
@ -1959,8 +2018,8 @@ void list_mempage(const char *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(list_mempage, list module using memory page information)
|
FINSH_FUNCTION_EXPORT(list_mempage, list module using memory page information)
|
||||||
#endif
|
#endif /* RT_USING_FINSH */
|
||||||
|
|
||||||
#endif
|
#endif /* RT_USING_SLAB */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
12
src/module.h
12
src/module.h
|
@ -222,7 +222,19 @@ typedef struct
|
||||||
} Elf32_Phdr;
|
} Elf32_Phdr;
|
||||||
|
|
||||||
/* p_type */
|
/* p_type */
|
||||||
|
#define PT_NULL 0
|
||||||
#define PT_LOAD 1
|
#define PT_LOAD 1
|
||||||
|
#define PT_DYNAMIC 2
|
||||||
|
#define PT_INTERP 3
|
||||||
|
#define PT_NOTE 4
|
||||||
|
#define PT_SHLIB 5
|
||||||
|
#define PT_PHDR 6
|
||||||
|
#define PT_TLS 7
|
||||||
|
#define PT_NUM 8
|
||||||
|
#define PT_LOOS 0x60000000
|
||||||
|
#define PT_HIOS 0x6fffffff
|
||||||
|
#define PT_LOPROC 0x70000000
|
||||||
|
#define PT_HIPROC 0x7fffffff
|
||||||
|
|
||||||
/* p_flags */
|
/* p_flags */
|
||||||
#define PF_X 1
|
#define PF_X 1
|
||||||
|
|
Loading…
Reference in New Issue