Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Keyboard Man_俊
rt-thread
提交
abd19b8d
R
rt-thread
项目概览
Keyboard Man_俊
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
abd19b8d
编写于
8月 03, 2015
作者:
B
Bernard Xiong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Kernel] More better support for module.
上级
db73a31e
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
296 addition
and
222 deletion
+296
-222
include/rtdef.h
include/rtdef.h
+4
-1
src/module.c
src/module.c
+280
-221
src/module.h
src/module.h
+12
-0
未找到文件。
include/rtdef.h
浏览文件 @
abd19b8d
...
...
@@ -892,7 +892,8 @@ enum
RTGRAPHIC_PIXEL_FORMAT_BGR565
=
RTGRAPHIC_PIXEL_FORMAT_RGB565P
,
RTGRAPHIC_PIXEL_FORMAT_RGB666
,
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 */
rt_uint32_t
vstart_addr
;
/**< VMA base address for the
first LOAD segment. */
rt_uint8_t
*
module_space
;
/**< module memory space */
void
*
module_entry
;
/**< the entry address of module */
...
...
src/module.c
浏览文件 @
abd19b8d
...
...
@@ -33,6 +33,10 @@
#include <rtthread.h>
#include <rtm.h>
#ifdef RT_USING_FINSH
#include <finsh.h>
#endif
#ifdef RT_USING_MODULE
#include "module.h"
...
...
@@ -48,6 +52,18 @@
#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))
#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
#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_end
=
RT_NULL
;
#if defined(__IAR_SYSTEMS_ICC__)
/* for IAR compiler */
#pragma section="RTMSymTab"
#endif
/**
* @ingroup SystemInit
*
...
...
@@ -94,16 +114,38 @@ int rt_system_module_init(void)
_rt_module_symtab_begin
=
(
struct
rt_module_symtab
*
)
&
RTMSymTab
$$
Base
;
_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
#ifdef RT_USING_SLAB
/* initialize heap semaphore */
rt_sem_init
(
&
mod_sem
,
"module"
,
1
,
RT_IPC_FLAG_FIFO
);
#endif
return
0
;
return
0
;
}
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
)
{
/* find in kernel symbol table */
...
...
@@ -145,7 +187,9 @@ static int rt_module_arm_relocate(struct rt_module *module,
Elf32_Sword
addend
,
offset
;
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
))
{
case
R_ARM_NONE
:
...
...
@@ -206,10 +250,10 @@ static int rt_module_arm_relocate(struct rt_module *module,
j1
=
(
lower
>>
13
)
&
1
;
j2
=
(
lower
>>
11
)
&
1
;
offset
=
(
sign
<<
24
)
|
((
~
(
j1
^
sign
)
&
1
)
<<
23
)
|
((
~
(
j2
^
sign
)
&
1
)
<<
22
)
|
((
upper
&
0x03ff
)
<<
12
)
|
((
lower
&
0x07ff
)
<<
1
);
((
~
(
j1
^
sign
)
&
1
)
<<
23
)
|
((
~
(
j2
^
sign
)
&
1
)
<<
22
)
|
((
upper
&
0x03ff
)
<<
12
)
|
((
lower
&
0x07ff
)
<<
1
);
if
(
offset
&
0x01000000
)
offset
-=
0x02000000
;
offset
+=
sym_val
-
(
Elf32_Addr
)
where
;
...
...
@@ -227,11 +271,11 @@ static int rt_module_arm_relocate(struct rt_module *module,
j1
=
sign
^
(
~
(
offset
>>
23
)
&
1
);
j2
=
sign
^
(
~
(
offset
>>
22
)
&
1
);
*
(
rt_uint16_t
*
)
where
=
(
rt_uint16_t
)((
upper
&
0xf800
)
|
(
sign
<<
10
)
|
((
offset
>>
12
)
&
0x03ff
));
(
sign
<<
10
)
|
((
offset
>>
12
)
&
0x03ff
));
*
(
rt_uint16_t
*
)(
where
+
2
)
=
(
rt_uint16_t
)((
lower
&
0xd000
)
|
(
j1
<<
13
)
|
(
j2
<<
11
)
|
((
offset
>>
1
)
&
0x07ff
));
(
j1
<<
13
)
|
(
j2
<<
11
)
|
((
offset
>>
1
)
&
0x07ff
));
upper
=
*
(
rt_uint16_t
*
)
where
;
lower
=
*
(
rt_uint16_t
*
)((
Elf32_Addr
)
where
+
2
);
break
;
...
...
@@ -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
,
void
*
module_ptr
)
{
rt_uint8_t
*
ptr
=
RT_NULL
;
rt_module_t
module
=
RT_NULL
;
rt_bool_t
linked
=
RT_FALSE
;
rt_uint32_t
index
,
module_size
=
0
;
Elf32_Addr
vstart_addr
,
vend_addr
;
rt_bool_t
has_vstart
;
RT_ASSERT
(
module_ptr
!=
RT_NULL
);
...
...
@@ -365,12 +410,62 @@ static struct rt_module *_load_shared_object(const char *name,
}
/* get the ELF image size */
has_vstart
=
RT_FALSE
;
vstart_addr
=
vend_addr
=
RT_NULL
;
for
(
index
=
0
;
index
<
elf_module
->
e_phnum
;
index
++
)
{
if
(
phdr
[
index
].
p_type
==
PT_LOAD
)
module_size
+=
phdr
[
index
].
p_memsz
;
if
(
phdr
[
index
].
p_type
!=
PT_LOAD
)
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
)
{
rt_kprintf
(
"Module: size error
\n
"
);
...
...
@@ -384,6 +479,8 @@ static struct rt_module *_load_shared_object(const char *name,
if
(
!
module
)
return
RT_NULL
;
module
->
vstart_addr
=
vstart_addr
;
module
->
nref
=
0
;
/* allocate module space */
...
...
@@ -397,21 +494,21 @@ static struct rt_module *_load_shared_object(const char *name,
}
/* zero all space */
ptr
=
module
->
module_space
;
rt_memset
(
ptr
,
0
,
module_size
);
rt_memset
(
module
->
module_space
,
0
,
module_size
);
for
(
index
=
0
;
index
<
elf_module
->
e_phnum
;
index
++
)
{
if
(
phdr
[
index
].
p_type
==
PT_LOAD
)
{
rt_memcpy
(
ptr
+
phdr
[
index
].
p_p
addr
,
rt_memcpy
(
module
->
module_space
+
phdr
[
index
].
p_vaddr
-
vstart_
addr
,
(
rt_uint8_t
*
)
elf_module
+
phdr
[
index
].
p_offset
,
phdr
[
index
].
p_filesz
);
}
}
/* 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 */
for
(
index
=
0
;
index
<
elf_module
->
e_shnum
;
index
++
)
...
...
@@ -432,7 +529,7 @@ static struct rt_module *_load_shared_object(const char *name,
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
;
shdr
[
shdr
[
shdr
[
index
].
sh_link
].
sh_link
].
sh_offset
;
nr_reloc
=
(
rt_uint32_t
)(
shdr
[
index
].
sh_size
/
sizeof
(
Elf32_Rel
));
/* relocate every items */
...
...
@@ -448,7 +545,9 @@ static struct rt_module *_load_shared_object(const char *name,
(
ELF_ST_BIND
(
sym
->
st_info
)
==
STB_LOCAL
))
{
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
)
{
...
...
@@ -485,7 +584,7 @@ static struct rt_module *_load_shared_object(const char *name,
/* find .dynsym section */
rt_uint8_t
*
shstrab
;
shstrab
=
(
rt_uint8_t
*
)
module_ptr
+
shdr
[
elf_module
->
e_shstrndx
].
sh_offset
;
shdr
[
elf_module
->
e_shstrndx
].
sh_offset
;
if
(
rt_strcmp
((
const
char
*
)(
shstrab
+
shdr
[
index
].
sh_name
),
ELF_DYNSYM
)
==
0
)
break
;
}
...
...
@@ -500,7 +599,7 @@ static struct rt_module *_load_shared_object(const char *name,
symtab
=
(
Elf32_Sym
*
)((
rt_uint8_t
*
)
module_ptr
+
shdr
[
index
].
sh_offset
);
strtab
=
(
rt_uint8_t
*
)
module_ptr
+
shdr
[
shdr
[
index
].
sh_link
].
sh_offset
;
for
(
i
=
0
;
i
<
shdr
[
index
].
sh_size
/
sizeof
(
Elf32_Sym
);
i
++
)
for
(
i
=
0
;
i
<
shdr
[
index
].
sh_size
/
sizeof
(
Elf32_Sym
);
i
++
)
{
if
((
ELF_ST_BIND
(
symtab
[
i
].
st_info
)
==
STB_GLOBAL
)
&&
(
ELF_ST_TYPE
(
symtab
[
i
].
st_info
)
==
STT_FUNC
))
...
...
@@ -508,9 +607,9 @@ static struct rt_module *_load_shared_object(const char *name,
}
module
->
symtab
=
(
struct
rt_module_symtab
*
)
rt_malloc
(
count
*
sizeof
(
struct
rt_module_symtab
));
(
count
*
sizeof
(
struct
rt_module_symtab
));
module
->
nsym
=
count
;
for
(
i
=
0
,
count
=
0
;
i
<
shdr
[
index
].
sh_size
/
sizeof
(
Elf32_Sym
);
i
++
)
for
(
i
=
0
,
count
=
0
;
i
<
shdr
[
index
].
sh_size
/
sizeof
(
Elf32_Sym
);
i
++
)
{
rt_size_t
length
;
...
...
@@ -574,10 +673,12 @@ static struct rt_module* _load_relocated_object(const char *name,
/* allocate module */
module
=
(
struct
rt_module
*
)
rt_object_allocate
(
RT_Object_Class_Module
,
(
const
char
*
)
name
);
rt_object_allocate
(
RT_Object_Class_Module
,
(
const
char
*
)
name
);
if
(
module
==
RT_NULL
)
return
RT_NULL
;
module
->
vstart_addr
=
0
;
/* allocate module space */
module
->
module_space
=
rt_malloc
(
module_size
);
if
(
module
->
module_space
==
RT_NULL
)
...
...
@@ -661,11 +762,11 @@ static struct rt_module* _load_relocated_object(const char *name,
/* locate .dynsym and .dynstr */
symtab
=
(
Elf32_Sym
*
)((
rt_uint8_t
*
)
module_ptr
+
shdr
[
shdr
[
index
].
sh_link
].
sh_offset
);
shdr
[
shdr
[
index
].
sh_link
].
sh_offset
);
strtab
=
(
rt_uint8_t
*
)
module_ptr
+
shdr
[
shdr
[
shdr
[
index
].
sh_link
].
sh_link
].
sh_offset
;
shdr
[
shdr
[
shdr
[
index
].
sh_link
].
sh_link
].
sh_offset
;
shstrab
=
(
rt_uint8_t
*
)
module_ptr
+
shdr
[
elf_module
->
e_shstrndx
].
sh_offset
;
shdr
[
elf_module
->
e_shstrndx
].
sh_offset
;
nr_reloc
=
(
rt_uint32_t
)(
shdr
[
index
].
sh_size
/
sizeof
(
Elf32_Rel
));
/* relocate every items */
...
...
@@ -682,7 +783,7 @@ static struct rt_module* _load_relocated_object(const char *name,
(
ELF_ST_TYPE
(
sym
->
st_info
)
==
STT_OBJECT
))
{
if
(
rt_strncmp
((
const
char
*
)(
shstrab
+
shdr
[
sym
->
st_shndx
].
sh_name
),
ELF_RODATA
,
8
)
==
0
)
shdr
[
sym
->
st_shndx
].
sh_name
),
ELF_RODATA
,
8
)
==
0
)
{
/* relocate rodata section */
RT_DEBUG_LOG
(
RT_DEBUG_MODULE
,
(
"rodata
\n
"
));
...
...
@@ -690,7 +791,7 @@ static struct rt_module* _load_relocated_object(const char *name,
(
Elf32_Addr
)(
rodata_addr
+
sym
->
st_value
));
}
else
if
(
rt_strncmp
((
const
char
*
)
(
shstrab
+
shdr
[
sym
->
st_shndx
].
sh_name
),
ELF_BSS
,
5
)
==
0
)
(
shstrab
+
shdr
[
sym
->
st_shndx
].
sh_name
),
ELF_BSS
,
5
)
==
0
)
{
/* relocate bss section */
RT_DEBUG_LOG
(
RT_DEBUG_MODULE
,
(
"bss
\n
"
));
...
...
@@ -698,7 +799,7 @@ static struct rt_module* _load_relocated_object(const char *name,
(
Elf32_Addr
)
bss_addr
+
sym
->
st_value
);
}
else
if
(
rt_strncmp
((
const
char
*
)(
shstrab
+
shdr
[
sym
->
st_shndx
].
sh_name
),
ELF_DATA
,
6
)
==
0
)
ELF_DATA
,
6
)
==
0
)
{
/* relocate data section */
RT_DEBUG_LOG
(
RT_DEBUG_MODULE
,
(
"data
\n
"
));
...
...
@@ -710,8 +811,11 @@ static struct rt_module* _load_relocated_object(const char *name,
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
));
rt_module_arm_relocate
(
module
,
rel
,
(
Elf32_Addr
)((
rt_uint8_t
*
)
module
->
module_space
-
module_addr
+
sym
->
st_value
));
}
else
{
...
...
@@ -736,8 +840,11 @@ static struct rt_module* _load_relocated_object(const char *name,
}
else
{
rt_module_arm_relocate
(
module
,
rel
,
(
Elf32_Addr
)((
rt_uint8_t
*
)
module
->
module_space
-
module_addr
+
sym
->
st_value
));
rt_module_arm_relocate
(
module
,
rel
,
(
Elf32_Addr
)((
rt_uint8_t
*
)
module
->
module_space
-
module_addr
+
sym
->
st_value
));
}
}
rel
++
;
...
...
@@ -747,21 +854,107 @@ static struct rt_module* _load_relocated_object(const char *name,
return
module
;
}
#define RT_MODULE_ARG_MAX 8
static
int
_rt_module_split_arg
(
char
*
cmd
,
rt_size_t
length
,
char
*
argv
[])
{
int
argc
=
0
;
char
*
ptr
=
cmd
;
while
((
ptr
-
cmd
)
<
length
)
{
/* strip bank and tab */
while
((
*
ptr
==
' '
||
*
ptr
==
'\t'
)
&&
(
ptr
-
cmd
)
<
length
)
*
ptr
++
=
'\0'
;
/* check whether it's the end of line */
if
((
ptr
-
cmd
)
>=
length
)
break
;
/* handle string with quote */
if
(
*
ptr
==
'"'
)
{
argv
[
argc
++
]
=
++
ptr
;
/* skip this string */
while
(
*
ptr
!=
'"'
&&
(
ptr
-
cmd
)
<
length
)
if
(
*
ptr
++
==
'\\'
)
ptr
++
;
if
((
ptr
-
cmd
)
>=
length
)
break
;
/* skip '"' */
*
ptr
++
=
'\0'
;
}
else
{
argv
[
argc
++
]
=
ptr
;
while
((
*
ptr
!=
' '
&&
*
ptr
!=
'\t'
)
&&
(
ptr
-
cmd
)
<
length
)
ptr
++
;
}
if
(
argc
>=
RT_MODULE_ARG_MAX
)
break
;
}
return
argc
;
}
/* module main thread entry */
static
void
module_main_entry
(
void
*
parameter
)
{
int
argc
;
char
*
argv
[
RT_MODULE_ARG_MAX
];
typedef
int
(
*
main_func_t
)(
int
argc
,
char
**
argv
);
rt_module_t
module
=
(
rt_module_t
)
parameter
;
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
));
argc
=
_rt_module_split_arg
((
char
*
)
module
->
module_cmd_line
,
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 */
((
main_func_t
)
module
->
module_entry
)(
argc
,
argv
);
return
;
}
/**
* This function will load a module from memory and create a thread for it
* This function will load a module with a main function from memory and create a
* main thread for it
*
* @param name the name of module, which shall be unique
* @param module_ptr the memory address of module image
* @argc the count of argument
* @argd the argument data, which should be a
*
* @return the module object
*/
rt_module_t
rt_module_load
(
const
char
*
name
,
void
*
module_ptr
)
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_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 */
if
(
rt_memcmp
(
elf_module
->
e_ident
,
RTMMAG
,
SELFMAG
)
!=
0
&&
...
...
@@ -801,10 +994,24 @@ rt_module_t rt_module_load(const char *name, void *module_ptr)
/* 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
;
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 */
module
->
nref
++
;
...
...
@@ -822,8 +1029,9 @@ rt_module_t rt_module_load(const char *name, void *module_ptr)
/* create module thread */
module
->
module_thread
=
rt_thread_create
(
name
,
(
void
(
*
)(
void
*
))
module
->
module_entry
,
RT_NULL
,
2048
,
RT_THREAD_PRIORITY_MAX
-
2
,
10
);
module_main_entry
,
module
,
RT_USING_MODULE_STKSZ
,
RT_USING_MODULE_PRIO
,
10
);
RT_DEBUG_LOG
(
RT_DEBUG_MODULE
,
(
"thread entry 0x%x
\n
"
,
module
->
module_entry
));
...
...
@@ -851,166 +1059,17 @@ rt_module_t rt_module_load(const char *name, void *module_ptr)
return
module
;
}
#define RT_MODULE_ARG_MAX 8
static
int
_rt_module_split_arg
(
char
*
cmd
,
rt_size_t
length
,
char
*
argv
[])
{
int
argc
=
0
;
char
*
ptr
=
cmd
;
while
((
ptr
-
cmd
)
<
length
)
{
/* strip bank and tab */
while
((
*
ptr
==
' '
||
*
ptr
==
'\t'
)
&&
(
ptr
-
cmd
)
<
length
)
*
ptr
++
=
'\0'
;
/* check whether it's the end of line */
if
((
ptr
-
cmd
)
>=
length
)
break
;
/* handle string with quote */
if
(
*
ptr
==
'"'
)
{
argv
[
argc
++
]
=
++
ptr
;
/* skip this string */
while
(
*
ptr
!=
'"'
&&
(
ptr
-
cmd
)
<
length
)
if
(
*
ptr
++
==
'\\'
)
ptr
++
;
if
((
ptr
-
cmd
)
>=
length
)
break
;
/* skip '"' */
*
ptr
++
=
'\0'
;
}
else
{
argv
[
argc
++
]
=
ptr
;
while
((
*
ptr
!=
' '
&&
*
ptr
!=
'\t'
)
&&
(
ptr
-
cmd
)
<
length
)
ptr
++
;
}
if
(
argc
>=
RT_MODULE_ARG_MAX
)
break
;
}
return
argc
;
}
/* module main thread entry */
static
void
module_main_entry
(
void
*
parameter
)
{
int
argc
;
char
*
argv
[
RT_MODULE_ARG_MAX
];
typedef
int
(
*
main_func_t
)(
int
argc
,
char
**
argv
);
rt_module_t
module
=
(
rt_module_t
)
parameter
;
if
(
module
==
RT_NULL
||
module
->
module_cmd_line
==
RT_NULL
)
return
;
rt_memset
(
argv
,
0x00
,
sizeof
(
argv
));
argc
=
_rt_module_split_arg
((
char
*
)
module
->
module_cmd_line
,
module
->
module_cmd_size
,
argv
);
if
(
argc
==
0
)
return
;
/* do the main function */
((
main_func_t
)
module
->
module_entry
)(
argc
,
argv
);
return
;
}
/**
* This function will load a module with a main function from memory and create a
* main thread for it
* 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
* @argc the count of argument
* @argd the argument data, which should be a
*
* @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_
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 excutable program
\n
"
);
return
RT_NULL
;
}
if
(
module
==
RT_NULL
)
return
RT_NULL
;
/* init module object container */
rt_module_init_object_container
(
module
);
/* 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
/* 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 */
module
->
module_thread
=
rt_thread_create
(
name
,
module_main_entry
,
module
,
2048
,
RT_THREAD_PRIORITY_MAX
-
2
,
10
);
/* set module id */
module
->
module_thread
->
module_id
=
(
void
*
)
module
;
module
->
parent
.
flag
=
RT_MODULE_FLAG_WITHENTRY
;
/* startup main 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
;
return
rt_module_do_main
(
name
,
module_ptr
,
RT_NULL
,
0
);
}
#ifdef RT_USING_DFS
...
...
@@ -1132,33 +1191,33 @@ rt_module_t rt_module_exec_cmd(const char *path, const char* cmd_line, int size)
char
*
name
,
*
buffer
,
*
offset_ptr
;
struct
rt_module
*
module
=
RT_NULL
;
name
=
buffer
=
RT_NULL
;
name
=
buffer
=
RT_NULL
;
RT_DEBUG_NOT_IN_INTERRUPT
;
/* check parameters */
RT_ASSERT
(
path
!=
RT_NULL
);
/* get file size */
/* get file size */
if
(
stat
(
path
,
&
s
)
!=
0
)
{
rt_kprintf
(
"Module: access %s failed
\n
"
,
path
);
goto
__exit
;
}
/* allocate buffer to save program */
/* allocate buffer to save program */
offset_ptr
=
buffer
=
(
char
*
)
rt_malloc
(
s
.
st_size
);
if
(
buffer
==
RT_NULL
)
{
rt_kprintf
(
"Module: out of memory
\n
"
);
goto
__exit
;
goto
__exit
;
}
fd
=
open
(
path
,
O_RDONLY
,
0
);
if
(
fd
<
0
)
{
rt_kprintf
(
"Module: open %s failed
\n
"
,
path
);
goto
__exit
;
goto
__exit
;
}
do
...
...
@@ -1175,12 +1234,12 @@ rt_module_t rt_module_exec_cmd(const char *path, const char* cmd_line, int size)
if
((
rt_uint32_t
)
offset_ptr
-
(
rt_uint32_t
)
buffer
!=
s
.
st_size
)
{
rt_kprintf
(
"Module: read file failed
\n
"
);
goto
__exit
;
goto
__exit
;
}
/* get module */
/* get module */
name
=
_module_name
(
path
);
/* execute module */
/* execute module */
module
=
rt_module_do_main
(
name
,
(
void
*
)
buffer
,
cmd_line
,
size
);
__exit:
...
...
@@ -1224,7 +1283,7 @@ rt_err_t rt_module_destroy(rt_module_t module)
{
#ifdef RT_USING_SEMAPHORE
/* 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
)
{
object
=
rt_list_entry
(
list
->
next
,
struct
rt_object
,
list
);
...
...
@@ -1362,12 +1421,12 @@ rt_err_t rt_module_destroy(rt_module_t module)
rt_timer_delete
((
rt_timer_t
)
object
);
}
}
/* delete command line */
if
(
module
->
module_cmd_line
!=
RT_NULL
)
{
rt_free
(
module
->
module_cmd_line
);
}
/* delete command line */
if
(
module
->
module_cmd_line
!=
RT_NULL
)
{
rt_free
(
module
->
module_cmd_line
);
}
}
#ifdef RT_USING_SLAB
...
...
@@ -1615,8 +1674,8 @@ void *rt_module_malloc(rt_size_t size)
RT_DEBUG_NOT_IN_INTERRUPT
;
nunits
=
(
size
+
sizeof
(
struct
rt_mem_head
)
-
1
)
/
sizeof
(
struct
rt_mem_head
)
+
1
;
sizeof
(
struct
rt_mem_head
)
+
1
;
RT_ASSERT
(
size
!=
0
);
RT_ASSERT
(
nunits
!=
0
);
...
...
@@ -1659,7 +1718,7 @@ void *rt_module_malloc(rt_size_t size)
/* allocate pages from system heap */
npage
=
(
size
+
sizeof
(
struct
rt_mem_head
)
+
RT_MM_PAGE_SIZE
-
1
)
/
RT_MM_PAGE_SIZE
;
RT_MM_PAGE_SIZE
;
if
((
up
=
(
struct
rt_mem_head
*
)
rt_module_malloc_page
(
npage
))
==
RT_NULL
)
return
RT_NULL
;
...
...
@@ -1725,8 +1784,8 @@ void rt_module_free(rt_module_t module, void *addr)
if
((
b
->
size
*
sizeof
(
struct
rt_page_info
)
%
RT_MM_PAGE_SIZE
)
!=
0
)
{
rt_size_t
nunits
=
npage
*
RT_MM_PAGE_SIZE
/
sizeof
(
struct
rt_mem_head
);
RT_MM_PAGE_SIZE
/
sizeof
(
struct
rt_mem_head
);
/* split memory */
r
=
b
+
nunits
;
r
->
next
=
b
->
next
;
...
...
@@ -1762,8 +1821,8 @@ void rt_module_free(rt_module_t module, void *addr)
if
((
n
->
size
*
sizeof
(
struct
rt_page_info
)
%
RT_MM_PAGE_SIZE
)
!=
0
)
{
rt_size_t
nunits
=
npage
*
RT_MM_PAGE_SIZE
/
sizeof
(
struct
rt_mem_head
);
RT_MM_PAGE_SIZE
/
sizeof
(
struct
rt_mem_head
);
/* split memory */
r
=
n
+
nunits
;
r
->
next
=
n
->
next
;
...
...
@@ -1848,8 +1907,8 @@ void *rt_module_realloc(void *ptr, rt_size_t size)
}
nunits
=
(
size
+
sizeof
(
struct
rt_mem_head
)
-
1
)
/
sizeof
(
struct
rt_mem_head
)
+
1
;
sizeof
(
struct
rt_mem_head
)
+
1
;
b
=
(
struct
rt_mem_head
*
)
ptr
-
1
;
if
(
nunits
<=
b
->
size
)
...
...
@@ -1959,8 +2018,8 @@ void list_mempage(const char *name)
}
}
FINSH_FUNCTION_EXPORT
(
list_mempage
,
list
module
using
memory
page
information
)
#endif
#endif
/* RT_USING_FINSH */
#endif
#endif
/* RT_USING_SLAB */
#endif
src/module.h
浏览文件 @
abd19b8d
...
...
@@ -222,7 +222,19 @@ typedef struct
}
Elf32_Phdr
;
/* p_type */
#define PT_NULL 0
#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 */
#define PF_X 1
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录