Execute elf

426 views
Skip to first unread message

Герман Цвветков

unread,
Feb 28, 2018, 7:26:35 AM2/28/18
to NuttX
Hello.

I'm try to run an application from sd card. How i can do that, and where i can read about it?
I read this doc: http://nuttx.org/doku.php?id=wiki:nshhowtos:nshapplications, and seen a Nuttx youtube chanel. Sd card works correctly, i can write and read files.
But if i try execute hello file from examles/elf it dosn't work.

Germann.

patacongo

unread,
Feb 28, 2018, 7:39:27 AM2/28/18
to NuttX
There are examples at apps/examples/elf, apps/examples/posix_spawn.  See also realates apps/examples/module and apps/examples/sotest. This also use ELF modules apps/examples/thttpd.

There are sample configurations at nuttx/configs/sama5d4-ek/elf, configs/stm32f4discovery/elf, and configs/stm32f4discover/posix_spawn (also modules, sotest, and thttpd).

You have read the best Wiki page.  There is a little more information at http://nuttx.org/doku.php?id=wiki:nshhowtos:elf-debug and http://nuttx.org/doku.php?id=wiki:nxinternal:kmodules-sharedlibs


Герман Цвветков

unread,
Mar 1, 2018, 5:19:30 AM3/1/18
to NuttX
Probably i locate my problem. 
I use stm32f103 blue pill for trying and debug
Please help me, if i do something wrong:
1. I copy elf configs from stm32f4discovery/elf
2. make nuttx with "nsh_main" entry point
3. copy elf files from apps/examples/elf/tests to sd card
4. flash nuttx to blu pill 
and: 
NuttShell (NSH)
nsh> mount -t vfat /dev/mmcsd0 /mnt/sdcard
nsh>
nsh> ls -l /mnt/sdcard/hello
 -rw-rw-rw-    1792 /mnt/sdcard/hello
nsh>
nsh> /mnt/sdcard/hello
nsh: /mnt/sdcard/hello: command not found

Germann

patacongo

unread,
Mar 1, 2018, 9:25:34 AM3/1/18
to NuttX
There could be issues with the "Blue Pill".  It does not have very much SRAM.  In order to execute the ELF file, it has to be copied into SRAM first.

The "command not found" error is coming from NSH.

nsh_parse.c:const char g_fmtcmdnotfound[]    = "nsh: %s: command not found\n";

Which the only relevant usage is at:

813 static int cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
814 {
815   nsh_output(vtbl, g_fmtcmdnotfound, argv[0]);
816   return ERROR;
817 }

Which is the default handler set up in nsh_command() and not related to executing ELF files.

Do you have CONFIG_NSH_FILE_APPS=y in the configuration?  You also need CONFIG_LIBC_EXECFUNCS=y.  It should work like the example here:  http://www.nuttx.org/doku.php?id=wiki:nshhowtos:nshapplications#executing_application_from_a_file_system

You might also turn on BINFMT debug output to see it if ever attempts to load the ELF file:  CONFIG_DEBUG_BINFMT=y, CONFIG_DEBUG_BINFMT_ERROR, CONFIG_DEBUG_BINFMT_WARN, and CONFIG_DEBUG_BINFMT_INFO.

Герман Цвветков

unread,
Mar 2, 2018, 3:05:18 AM3/2/18
to NuttX
Thanks for your attention.
I attach my defconfig file.
For build examples/elf, in "Make defs" also added 
#elf flags
CELFFLAGS = $(CFLAGS) -mlong-calls
LDELFFLAGS = -r -e main -T$(TOPDIR)/binfmt/libelf/gnu-elf.ld -nostdlib

I see what the all of needed configs is fine. But may be need some more accuracy memory configs?

defconfig

Герман Цвветков

unread,
Mar 5, 2018, 3:01:31 AM3/5/18
to NuttX
Update.
I apply debug options and it's my output:
nsh> /mnt/sdcard/hello
builtin_loadbinary: ERROR: FIOC_FILENAME ioctl failed: 88
exec: ERROR: Failed to load program '/mnt/sdcard/hello': 88
nsh: /mnt/sdcard/hello: command not found


пятница, 2 марта 2018 г., 11:05:18 UTC+3 пользователь Герман Цвветков написал:

patacongo

unread,
Mar 5, 2018, 9:05:32 AM3/5/18
to NuttX
> nsh> /mnt/sdcard/hello
> builtin_loadbinary: ERROR: FIOC_FILENAME ioctl failed: 88
> exec: ERROR: Failed to load program '/mnt/sdcard/hello': 88
> nsh: /mnt/sdcard/hello: command not found

Look in included/errno.h to see what the error 88 means:

295 #define ENOSYS              88
296 #define ENOSYS_STR          "Function not implemented"

builtin_loadbinary() is in nuttx/binfmt/builtin.c.  There you can see:

110   /* If this file is a BINFS file system, then we can recover the name of
111    * the file using the FIOC_FILENAME ioctl() call.
112    */
113
114   ret = ioctl(fd, FIOC_FILENAME, (unsigned long)((uintptr_t)&filename));
115   if (ret < 0)
116     {
117       int errval = get_errno();
118       berr("ERROR: FIOC_FILENAME ioctl failed: %d\n", errval);
119       close(fd);
120       return -errval;
121     }

That is not an error (at least not if the file is an ELF file).  Apparently you have the binfs file system enabled.  That just means that /mnt/sdcard/hello is not a binfs file.

The binfmt logic will go through each enabled binary format and attempt to load the file.  There error just means that it could not load the file as a binfs binary.  There is absolutely no evidence that it even attempted to try to load the file as an ELF binary.

You could put some debug output in the elf_loadbinary() in elf.c to see if it is ever called.  I bet that it is not.

Greg

Герман Цвветков

unread,
Mar 12, 2018, 6:56:51 AM3/12/18
to NuttX


You could put some debug output in the elf_loadbinary() in elf.c to see if it is ever called.  I bet that it is not.

Greg


Yes, you're right.  This function is never called, and it's no have any declaration in disassembly of nuttx

patacongo

unread,
Mar 12, 2018, 9:42:26 AM3/12/18
to NuttX

Yes, you're right.  This function is never called, and it's no have any declaration in disassembly of nuttx

That means you have some configuration problem.  You cannot execute ELF files until you fix those.  Most likely there are some unmet dependencies. 

Герман Цвветков

unread,
Mar 13, 2018, 10:13:35 AM3/13/18
to NuttX
I resolve a part of problem.

All of it's because in stm32f103-minimum/src/stm32_bringup.c no have any reference to elf_initialize(). After i past it, elf_loadbinary() from elf.c called each time for run elf files. 

But i have new problem. If i use some of standard function, like printf(), i get this fail:
elf_symvalue: SHN_UNDEF: Exported symbol "puts" not found
elf_relocate: Section 2 reloc 0: Failed to get value of symbol[18]: -2
elf_loadbinary: Failed to bind symbols program binary: -2
exec: ERROR: Failed to load program '/mnt/sdcard/hello': 2
ERROR: execv failed: 2

How i understand, is this due to wrong library connection?

patacongo

unread,
Mar 13, 2018, 10:37:44 AM3/13/18
to NuttX
How i understand, is this due to wrong library connection?

This is a symbol table problem.  In order to link ELF binaries into the system, you must have a symbol table that contains the address mapping of all symbols exported by the base system to the loaded modules.

You set the symbol table with:

void exec_setsymtab(FAR const struct symtab_s *symtab, int nsymbols)

How you create the symbol table is up to you.  You will have to be very careful with the STM32F103-Minimum because there is not a lot of FLASH memory for large symbol tables.  The ELF examples in apps/examples all create a symbol table with just enough symbols to run the examples.

There is a tool in nuttx/tools called mksymtab.c that might be useful to you.  There are .csv files in the sytem that describe interfaces (may not all be up to date):

$ find . -name "*.csv"
./libc/libc.csv
./libc/math.csv
./syscall/syscall.csv

These .cvs files can be used by mksymtab.c to create huge symbol tables which you can then manually pare down to fit.  Usage of mksymtab.c is described in nuttx/tools/README.txt.

Greg

Герман Цвветков

unread,
Mar 16, 2018, 7:45:11 AM3/16/18
to NuttX
Sucsess!

Thanks for your help, Greg.
Now problem resolved. 

It's required a small change in nsh_main.c file:
#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
const struct symtab_s CONFIG_EXECFUNCS_SYMTAB[1];
const int nsym = sizeof(CONFIG_EXECFUNCS_SYMTAB) / sizeof(struct symtab_s);
#endif

...
//in nsh_main()
  /* Make sure that we are using our symbol table */

#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
  exec_setsymtab(CONFIG_EXECFUNCS_SYMTAB, nsym); // by default exec_setsymtab(CONFIG_EXECFUNCS_SYMTAB, 0);
#endif


 In default in this place number of symbols is not implemented. After i add calculation of nsyms, like in examples/elf/tests/mksymtab.sh, i can run sucsessful elf/tests/hello/hello file

NuttShell (NSH)
nsh> mount -t vfat /dev/mmcsd0 /mnt/sdcard
nsh>
nsh> /mnt/sdcard/hello
Getting ready to say "Hello, world"

Hello, world!
It has been said.

argc    = 1
argv    = 0x200046e4
argv[0] = (0x200046ec) "<noname>"
argv[1] = 0x0
Goodbye, world!

But, ho i realize for run some of difficult apps, with many of Nuttx advantages, on a BluePill, need many of optimisation work.

вторник, 13 марта 2018 г., 17:37:44 UTC+3 пользователь patacongo написал:

patacongo

unread,
Mar 16, 2018, 9:36:32 AM3/16/18
to NuttX
It is good to see you are making progress.

There are a couple of problems with this:

It's required a small change in nsh_main.c file:
#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
const struct symtab_s CONFIG_EXECFUNCS_SYMTAB[1];
const int nsym = sizeof(CONFIG_EXECFUNCS_SYMTAB) / sizeof(struct symtab_s);
#endif

...
//in nsh_main()
  /* Make sure that we are using our symbol table */

#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
  exec_setsymtab(CONFIG_EXECFUNCS_SYMTAB, nsym); // by default exec_setsymtab(CONFIG_EXECFUNCS_SYMTAB, 0);
#endif




But, ho i realize for run some of difficult apps, with many of Nuttx advantages, on a BluePill, need many of optimisation work.

вторник, 13 марта 2018 г., 17:37:44 UTC+3 пользователь patacongo написал:
How i understand, is this due to wrong library connection?

This is a symbol table problem.  In order to link ELF binaries into the system, you must have a symbol table that contains the address mapping of all symbols exported by the base system to the loaded modules.

You set the symbol table with:

void exec_setsymtab(FAR const struct symtab_s *symtab, int nsymbols)

How you create the symbol table is up to you.  You will have to be very careful with the STM32F103-Minimum because there is not a lot of FLASH memory for large symbol tables.  The ELF examples in apps/examples all create a symbol table with just enough symbols to run the examples.

There is a tool in nuttx/tools called mksymtab.c that might be useful to you.  There are .csv files in the sytem that describe interfaces (may not all be up to date):

$ find . -name "*.csv"
./libc/libc.csv
./libc/math.csv
./syscall/syscall.csv

These .cvs files can be used by mksymtab.c to create huge symbol tables which you can then manually pare down to fit.  Usage of mksymtab.c is described in nuttx/tools/README.txt.

Greg


That was a "kludge" that was put in for BINFS and not intended for general use.  A second problem is the exec_setsymbtab() is a non-stanard, internal OS function and cannot be called from applications in all configuration.

I am going to remove all of this.  It is wrong.

You should set up your symbol table in either your board bringup logic or using the logic of apps/system/symtab.  The logic is the same, it is just that the place is wrong.

Greg

patacongo

unread,
Mar 16, 2018, 9:40:24 AM3/16/18
to NuttX
Another option is to use the exec function which is like execve, be provides the symbol table information in parameters:

      ret = exec(filename, args, exports, nexports);

Jyeni Nii

unread,
Nov 28, 2019, 8:48:01 AM11/28/19
to NuttX
Hello, I happened to use the STM32F103C8 to try the same as you, but I failed. The system crashed while executing the hello application. Can you refer me to your configuration parameters? Please!

在 2018年3月16日星期五 UTC+8下午7:45:11,Герман Цвветков写道:
Reply all
Reply to author
Forward
0 new messages