List of init functions / sections / segments to call?

Asked by dave m.

Is there a list of functions, sections or segment function pointers to call to set up everything in newlib-nano? I have custom initialization code and linker script, so I can't use the default scripts and crt0, crti, crtbegin, etc. I haven't had much luck figuring out what the default linker scripts and startup code do -- there's too much conditional code, and I'm not sure what (if anything) is important or even relevant to my platform.

To be clear, this is a Cortex-M0 machine, and I get control of the CPU from the first instruction after reset. After setting up stack, hardware, copying initialized data to RAM and zeroing the bss segment, I would like to call newlib-nano libc initialization functions to set things up before calling constructors and then main().

Is there a list of these functions somewhere, or a list of linker-segment names containing initialization function pointers or whatever?

Thanks!

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
dave m.
Solved:
Last query:
Last reply:
Revision history for this message
Joey Ye (jinyun-ye) said :
#1

Call _start
2014-4-5 下午12:21于 "dave m." <email address hidden>写道:

> New question #246542 on GCC ARM Embedded:
> https://answers.launchpad.net/gcc-arm-embedded/+question/246542
>
> Is there a list of functions, sections or segment function pointers to
> call to set up everything in newlib-nano? I have custom initialization
> code and linker script, so I can't use the default scripts and crt0, crti,
> crtbegin, etc. I haven't had much luck figuring out what the default
> linker scripts and startup code do -- there's too much conditional code,
> and I'm not sure what (if anything) is important or even relevant to my
> platform.
>
> To be clear, this is a Cortex-M0 machine, and I get control of the CPU
> from the first instruction after reset. After setting up stack, hardware,
> copying initialized data to RAM and zeroing the bss segment, I would like
> to call newlib-nano libc initialization functions to set things up before
> calling constructors and then main().
>
> Is there a list of these functions somewhere, or a list of linker-segment
> names containing initialization function pointers or whatever?
>
> Thanks!
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
dave m. (z-launchpad-mersenne-com) said :
#2

My problem is, _start is defined in 76 different source files, mostly in crt0.c or crt0.S and all for machines that are different from mine. The closest one (I think) is newlib/libc/sys/arm/crt0.S, but that code is 494 lines and full of conditional code for different architectures, ROM monitors and other things.

From what I can tell, under what I think is the applicable #defines, all that actually happens is:

stack_pointer=_end_of_ram_;
memcpy( &_data, &_data_initializers );
memset( &_bss, 0, &_ebss - &_bss );
/* parse cmdline to get argc & argv */
main( argc, argv );

But when I do all that, it's not enough. (The problem I see is that the default FILE structures aren't set up correctly, so printf() crashes rather than eventually calling _write().)

There's something with _init and _fini, maybe _libc_init_array and _libc_fini_array, which looks promising, but I can't find my way through the #ifdefs and linker scripts. So that may be where I need info/help.

dhm@aluminum-debian:/var/tmp/gcc-arm-none-eabi-4_8-2014q1-20140314/src/newlib-nano-2.1$ find . -type f -print | xargs egrep -l '\<_start\>' | egrep -i '*.[cs]$'
./newlib/libc/machine/spu/spu-gmon.c
./newlib/libc/sys/tic80/crt0.c
./newlib/libc/sys/arm/crt0.S
./newlib/libc/sys/sysvi386/crt0.c
./newlib/libc/sys/linux/machine/i386/crt0.c
./newlib/libc/sys/h8300hms/crt0.S
./newlib/libc/sys/m88kbug/crt0.c
./newlib/libc/sys/d10v/crt0.S
./newlib/libc/sys/sysmec/crt0.S
./newlib/libc/sys/rdos/crt0.S
./newlib/libc/sys/sysnecv850/crt0.S
./newlib/libc/stdlib/__atexit.c
./libgloss/tic6x/crt0.S
./libgloss/sparc/crt0.S
./libgloss/frv/crt0.S
./libgloss/mcore/crt0.S
./libgloss/moxie/crt0.S
./libgloss/m68hc11/crt0.S
./libgloss/fr30/crt0.s
./libgloss/arm/redboot-crt0.S
./libgloss/arm/crt0.S
./libgloss/arm/linux-crt0.c
./libgloss/mt/crt0-16-002.S
./libgloss/mt/startup-ms2.S
./libgloss/mt/crt0.S
./libgloss/mt/startup-16-002.S
./libgloss/mt/crt0-16-003.S
./libgloss/mt/crt0-64-001.S
./libgloss/mt/startup-16-003.S
./libgloss/mt/startup-64-001.S
./libgloss/mt/crt0-ms2.S
./libgloss/rl78/crt0.S
./libgloss/m68k/crt0.S
./libgloss/m68k/fido.sc
./libgloss/m68k/fido-crt0.S
./libgloss/microblaze/crt4.S
./libgloss/microblaze/crt2.S
./libgloss/microblaze/linux-crt0.S
./libgloss/microblaze/crt3.S
./libgloss/microblaze/crt0.S
./libgloss/microblaze/crt1.S
./libgloss/d30v/crt0.S
./libgloss/cr16/crt1.S
./libgloss/mn10300/crt0_cygmon.S
./libgloss/mn10300/crt0_redboot.S
./libgloss/mn10300/crt0.S
./libgloss/mips/crt0_cfe.S
./libgloss/mips/crt0_cygmon.S
./libgloss/mips/crt0.S
./libgloss/i960/crt0.c
./libgloss/xstormy16/crt0_stub.s
./libgloss/xstormy16/crt0.s
./libgloss/mep/sim-crt0.S
./libgloss/mep/mep-gmon.c
./libgloss/mep/h_reset.c
./libgloss/m32r/crt0.S
./libgloss/rx/crt0.S
./libgloss/m32c/crt0.S
./libgloss/xc16x/crt0.S
./libgloss/lm32/crt0.S
./libgloss/aarch64/crt0.S
./libgloss/epiphany/crt0.S
./libgloss/crx/crt0.S
./libgloss/iq2000/crt0.S
./libgloss/rs6000/sim-crt0.S
./libgloss/rs6000/xil-crt0.S
./libgloss/rs6000/crt0.S
./libgloss/v850/crt0.S
./libgloss/sparc_leon/locore.S
./libgloss/sparc_leon/crt0.S
./libgloss/spu/crt0.S
./libgloss/mn10200/crt0.S
./libgloss/nds32/crt0.S
./libgloss/nds32/crt1.S
./libgloss/cris/lcrt0.c
./libgloss/hp74x/crt0.s

Revision history for this message
dave m. (z-launchpad-mersenne-com) said :
#3

For my purposes (mostly printf debugging) the following was adequate:

static void
xprintf( const char *fmt, ... )
{
    va_list ap;
    char buf[128];
    size_t blen = sizeof(buf);
    size_t i;

    va_start( ap, fmt );
    vasnprintf( buf, &blen, fmt, ap );
    for (i = 0; i < blen; ++i) xputchar( buf[i] );
    va_end( ap );
}

I'm not initializing the whole FILE subsystem correctly, but I don't particularly need full stdio buffering &c anyway.

Hope this helps somebody else!