From 2957cf6f52f54fe06325d0595b3f535477cf2262 Mon Sep 17 00:00:00 2001 From: parai Date: Sun, 20 Aug 2017 20:24:07 +0800 Subject: [PATCH] x86: bring up share object module on i386 machine 1. upddate kernel module to support i386 2. update libdl to support open *.so by absolute path 3. new test case bsp/x86/src/hello.c to test i386 module feature Signed-off-by: parai --- bsp/x86/Makefile | 44 ++++++++++++++++++++++++------ bsp/x86/applications/application.c | 9 ++++++ bsp/x86/drivers/console.c | 4 +-- bsp/x86/rtconfig.h | 7 ++++- bsp/x86/rtconfig.py | 2 +- bsp/x86/src/extract.sh | 28 +++++++++++++++++++ bsp/x86/src/hello.c | 36 ++++++++++++++++++++++++ bsp/x86/src/stdio.h | 18 ++++++++++++ bsp/x86/x86_ram.lds | 5 +++- components/libc/libdl/dlopen.c | 11 +++++--- src/module.c | 14 +++++++++- src/module.h | 7 +++++ 12 files changed, 167 insertions(+), 18 deletions(-) create mode 100755 bsp/x86/src/extract.sh create mode 100644 bsp/x86/src/hello.c create mode 100644 bsp/x86/src/stdio.h diff --git a/bsp/x86/Makefile b/bsp/x86/Makefile index 1befec136..cdb4f4ca8 100644 --- a/bsp/x86/Makefile +++ b/bsp/x86/Makefile @@ -1,17 +1,45 @@ -all:floppy.img - scons - mkdir -p tmp - sudo mount -t vfat floppy.img tmp -o loop - sudo cp rtthread.elf tmp/boot/oskernel - sudo umount tmp +CC = gcc -O0 -m32 -fno-builtin -fno-stack-protector -nostdinc -nostdlib +LD = ld -melf_i386 -nostdlib + +all: rtthread rtsym exe dll floppy.img + @mkdir -p tmp + @sudo mount -t vfat floppy.img tmp -o loop + @sudo cp -fv rtthread.elf tmp/boot/oskernel + @sudo rm tmp/bin/* -fr + @sudo cp out/* tmp/bin/ -fv + @sudo umount tmp + +rtthread: + @scons + +rtsym: + @./src/extract.sh ./rtthread-ia32.map ./src/rt_thread_sym.h + +obj: + mkdir -p obj + +out: + mkdir -p out + +dll: obj out + $(CC) -shared -s -fPIC -e main -Isrc src/hello.c -o out/hello.mo + +disasm: obj out + $(CC) -shared -S -fPIC -Isrc src/hello.c -o obj/hello.s + cat obj/hello.s + objdump --disassemble out/hello.mo + +exe: obj out + clean: scons -c clean - rm -fr build rtthread* + rm -fr build rtthread* out obj floppy.img: wget https://github.com/bajdcc/tinix/raw/master/floppy.img +# https://en.wikibooks.org/wiki/QEMU/Devices/Network run: - qemu-system-i386 -fda floppy.img -boot a -m 64M -serial stdio + qemu-system-i386 -fda floppy.img -boot a -m 64M -serial stdio -net nic,model=ne2k_pci diff --git a/bsp/x86/applications/application.c b/bsp/x86/applications/application.c index 3a2f6c9b8..38f974def 100644 --- a/bsp/x86/applications/application.c +++ b/bsp/x86/applications/application.c @@ -26,7 +26,12 @@ #ifdef RT_USING_DFS #include +#include #include "floppy.h" +#ifdef RT_USING_MODULE +#include +#endif +extern int elm_init(void); #endif /* components initialization for simulator */ @@ -41,6 +46,10 @@ void components_init(void) /* initialize the elm chan FatFS file system*/ elm_init(); #endif + +#ifdef RT_USING_MODULE + rt_system_module_init(); +#endif #endif } void rt_init_thread_entry(void *parameter) diff --git a/bsp/x86/drivers/console.c b/bsp/x86/drivers/console.c index 6ffe9a799..1c1eb05e0 100644 --- a/bsp/x86/drivers/console.c +++ b/bsp/x86/drivers/console.c @@ -29,7 +29,7 @@ extern void rt_serial_init(void); extern char rt_serial_getc(void); extern void rt_serial_putc(const char c); -static void rt_console_putc(int c); +void rt_console_putc(int c); /** * @addtogroup QEMU @@ -127,7 +127,7 @@ static void rt_cga_putc(int c) * * @param c the char to write */ -static void rt_console_putc(int c) +void rt_console_putc(int c) { rt_cga_putc(c); rt_serial_putc(c); diff --git a/bsp/x86/rtconfig.h b/bsp/x86/rtconfig.h index 47c996cc4..780a1abc9 100644 --- a/bsp/x86/rtconfig.h +++ b/bsp/x86/rtconfig.h @@ -17,7 +17,7 @@ /* SECTION: RT_DEBUG */ /* Thread Debug */ #define RT_DEBUG -#define RT_THREAD_DEBUG +#define RT_DEBUG_MODULE 0 #define RT_USING_OVERFLOW_CHECK @@ -69,6 +69,8 @@ /* SECTION: finsh, a C-Express shell */ #define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_USING_MSH_ONLY /* Using symbol table */ #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION @@ -175,4 +177,7 @@ /* #define RTGUI_IMAGE_XPM */ /* #define RTGUI_IMAGE_BMP */ +#define RT_USING_LIBDL +#define RT_USING_MODULE +#define MODULE_USING_386 #endif diff --git a/bsp/x86/rtconfig.py b/bsp/x86/rtconfig.py index e99ddfe32..c602315d0 100644 --- a/bsp/x86/rtconfig.py +++ b/bsp/x86/rtconfig.py @@ -33,7 +33,7 @@ BUILD = 'debug' if PLATFORM == 'gcc': # toolchains PREFIX = '' - CC = PREFIX + 'gcc -m32 -fno-builtin -fno-stack-protector' + CC = PREFIX + 'gcc -m32 -fno-builtin -fno-stack-protector -nostdinc' AS = PREFIX + 'gcc -m32' AR = PREFIX + 'ar' LINK = PREFIX + 'ld -melf_i386' diff --git a/bsp/x86/src/extract.sh b/bsp/x86/src/extract.sh new file mode 100755 index 000000000..89f8baef7 --- /dev/null +++ b/bsp/x86/src/extract.sh @@ -0,0 +1,28 @@ +#! /bin/sh + + +imap=$1 +iout=$2 + +echo "!!! extract symbol from $imap to $iout !!!" + +symlist="rt_kprintf \ +rt_kputs \ +rt_vsprintf \ +rt_sprintf \ +rt_snprintf \ +rt_thread_create \ +" + +echo "#ifndef RT_THREAD_SYM_H_H" > $iout +echo "#define RT_THREAD_SYM_H_H" >> $iout + +for sym in $symlist +do +dlim=`echo $sym | cut -b 1` +addr=`cat $imap | grep $sym | head -n 1 | cut -d $dlim -f 1` + +echo "#define __abs_$sym $addr" >> $iout +done + +echo "#endif /* RT_THREAD_SYM_H_H */" >> $iout diff --git a/bsp/x86/src/hello.c b/bsp/x86/src/hello.c new file mode 100644 index 000000000..a075f18ef --- /dev/null +++ b/bsp/x86/src/hello.c @@ -0,0 +1,36 @@ + +#include +const char* g_str = "Hello World!"; + +static int a = 1234; +int b = 5678; + +extern void rt_kprintf(const char* fmt,...); + +int add(int a, int b) +{ + return a+b; +} + +int main(int argc, char* argv[]) +{ + int i; + char str[32] = "Hello World\n"; + + for(i=0; i + +typedef unsigned int size_t; + +typedef int (*sprintf_fcn_t)(char *buf ,const char *format, ...); +typedef int (*snprintf_fcn_t)(char *buf, size_t size, const char *format, ...); +typedef void (*puts_fcn_t)(const char *str); +typedef void (*printf_fcn_t)(const char *fmt, ...); + +#define printf ((printf_fcn_t)__abs_rt_kprintf) +#define puts ((printf_fcn_t)__abs_rt_kputs) +#define sprintf ((printf_fcn_t)__abs_rt_sprintf) +#define snprintf ((printf_fcn_t)__abs_rt_snprintf) + +#endif diff --git a/bsp/x86/x86_ram.lds b/bsp/x86/x86_ram.lds index 27fe39270..afac69f04 100644 --- a/bsp/x86/x86_ram.lds +++ b/bsp/x86/x86_ram.lds @@ -21,10 +21,13 @@ SECTIONS KEEP(*(VSymTab)) __vsymtab_end = .; . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)); + __rtmsymtab_end = .; } . = ALIGN(4); - .rodata : { *(.rodata) } + .rodata : { *(.rodata*) } . = ALIGN(4); .data : { *(.data) } diff --git a/components/libc/libdl/dlopen.c b/components/libc/libdl/dlopen.c index 5e063eed9..2c091079b 100644 --- a/components/libc/libdl/dlopen.c +++ b/components/libc/libdl/dlopen.c @@ -27,7 +27,7 @@ void* dlopen(const char *filename, int flags) /* check parameters */ RT_ASSERT(filename != RT_NULL); - if (filename[0] != '/') /* it's a absolute path, use it directly */ + if (filename[0] != '/') /* it's a relative path, prefix with MODULE_ROOT_DIR */ { fullpath = rt_malloc(strlen(def_path) + strlen(filename) + 2); @@ -37,8 +37,7 @@ void* dlopen(const char *filename, int flags) } else { - rt_kprintf("use absolute path\n"); - return RT_NULL; + fullpath = (char*)filename; /* absolute path, use it directly */ } /* find in module list */ @@ -47,7 +46,11 @@ void* dlopen(const char *filename, int flags) if(module != RT_NULL) module->nref++; else module = rt_module_open(fullpath); - rt_free(fullpath); + if(fullpath != filename) + { + rt_free(fullpath); + } + return (void*)module; } diff --git a/src/module.c b/src/module.c index c1a347565..888701930 100644 --- a/src/module.c +++ b/src/module.c @@ -27,6 +27,7 @@ * 2012-11-23 Bernard using RT_DEBUG_LOG instead of rt_kprintf. * 2012-11-28 Bernard remove rt_current_module and user * can use rt_module_unload to remove a module. + * 2017-08-20 parai support intel 386 machine */ #include @@ -223,6 +224,10 @@ static int rt_module_arm_relocate(struct rt_module *module, *where &= 0xf000000f; *where |= 0x01a0f000; break; +#ifdef MODULE_USING_386 + case R_386_GLOB_DAT: + case R_386_JUMP_SLOT: +#endif case R_ARM_GLOB_DAT: case R_ARM_JUMP_SLOT: *where = (Elf32_Addr)sym_val; @@ -236,6 +241,9 @@ static int rt_module_arm_relocate(struct rt_module *module, RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_GOT_BREL: 0x%x -> 0x%x 0x%x\n", where, *where, sym_val)); break; +#endif +#ifdef MODULE_USING_386 + case R_386_RELATIVE: #endif case R_ARM_RELATIVE: *where = (Elf32_Addr)sym_val + *where; @@ -543,7 +551,11 @@ static struct rt_module *_load_shared_object(const char *name, sym->st_shndx)); if ((sym->st_shndx != SHT_NULL) || - (ELF_ST_BIND(sym->st_info) == STB_LOCAL)) + (ELF_ST_BIND(sym->st_info) == STB_LOCAL) +#ifdef MODULE_USING_386 + || ( (ELF_ST_BIND(sym->st_info) == STB_GLOBAL) && (ELF_ST_TYPE(sym->st_info) == STT_OBJECT) ) +#endif + ) { rt_module_arm_relocate(module, rel, (Elf32_Addr)(module->module_space diff --git a/src/module.h b/src/module.h index 1ae9eedbe..90d4dc952 100644 --- a/src/module.h +++ b/src/module.h @@ -208,6 +208,13 @@ typedef struct #define R_ARM_THM_JUMP24 30 #define R_ARM_V4BX 40 +/* + * Relocation type for arm + */ +#define R_386_GLOB_DAT 6 +#define R_386_JUMP_SLOT 7 +#define R_386_RELATIVE 8 + /* Program Header */ typedef struct {