This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: Initialize data section in arm/crt0.S
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: "Pilhofer, Frank" <Frank dot Pilhofer at zuehlke dot com>
- Cc: "newlib at sourceware dot org" <newlib at sourceware dot org>
- Date: Mon, 14 Jul 2014 16:40:42 +0100
- Subject: Re: Initialize data section in arm/crt0.S
- Authentication-results: sourceware.org; auth=none
- References: <7b0d9c60e7aa48b79a38bae524fe315d at zrhex030 dot ads dot zuehlke dot com>
On 14/07/14 15:33, Pilhofer, Frank wrote:
> Hi,
>
> I am targeting a barebones STM32F0 Cortex-M0 using gcc-4.7.4 and newlib-2.1.0 with nano.specs.
>
> I figured out that the startup code from newlib-2.1.0/libgloss/arm/crt0.S gets used. It initializes the C/C++ runtime environment, provides initialization hooks, and eventually calls main. It looks sensible, so I would like to use it (i.e., use _start as the reset vector) instead of rolling my own.
>
> However, while the code does zero out the BSS segment and calls C++ constructors (__libc_init_array), it does not initialize the data section. So when I get to main, static data is not initialized as it should be.
>
> The attached patch adds data segment initialization.
>
> The gcc-arm-embedded folks suggest that data segment initialization should happen in CPU-specific startup code, i.e., in the code that defines the vector table. Not sure if I agree. But in that case, BSS zeroization should be removed from crt0.S: either do both, or do neither.
>
I don't think this is right. The standard crt0 is supposed to work with
conventional loadable image files (like an ELF executable). Such images
have initialized data in the correct location; on the other hand, the
zero-initialized data does not exist in the image and the file format
just specifies how large the uninitialized data segment is. A real
loader (such as in Linux) would do the zero-initialization for the code,
but there's no loader in a bare-metal system, so it has to do it itself.
(It should also be harmless if this is done twice, since in that case
we'd just be writing zeros to memory that already contains zeros ;-)
Furthermore __data_load__ is not a standard symbol exported by linker
scripts, so this would just break most uses of this file.
It looks to me as though you've got a very specialized environment where
you're copying an image out of, for example, flash. It's quite possible
you're going to have to roll your own crt0 for this sort of situation.
R.
> Thanks,
> Frank
>
>
> --
> Frank Pilhofer
> Zühlke Engineering GmbH
>
>
> crt0.S.patch
>
>
> --- newlib-2.1.0/libgloss/arm/crt0.S.orig 2013-10-14 17:15:12.000000000 +0200
> +++ newlib-2.1.0/libgloss/arm/crt0.S 2014-07-14 16:03:31.997315300 +0200
> @@ -260,8 +260,15 @@
> .thumb_func
> __change_mode:
> #endif
> -
> bl FUNCTION (memset)
> +
> + /* Initialize .data section. */
> + ldr a1, .LC3 /* First arg: start of .data section */
> + ldr a2, .LC3+4 /* Second arg: start of initializers in ROM */
> + ldr a3, .LC3+8 /* Third arg: length of .data section. */
> + subs a3, a3, a1
> + bl FUNCTION (memcpy)
> +
> #if !defined (ARM_RDP_MONITOR) && !defined (ARM_RDI_MONITOR)
> /* Changes by toralf: Taken from libgloss/m68k/crt0.S
> * initialize target specific stuff. Only execute these
> @@ -485,6 +492,11 @@
> .word __bss_start__
> .LC2:
> .word __bss_end__
> +.LC3:
> + .word __data_start__
> + .word __data_load__
> + .word __data_end__
> +
> #ifdef __USES_INITFINI__
> #ifdef _LITE_EXIT
> .Latexit:
>