avr-chat
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-chat] Startup code.


From: Erik Christiansen
Subject: Re: [avr-chat] Startup code.
Date: Thu, 23 Sep 2010 01:49:42 +1000
User-agent: Mutt/1.5.17+20080114 (2008-01-14)

On Wed, Sep 22, 2010 at 04:37:37PM +0200, Robert von Knobloch wrote:
> OK Erik,
> 
> why did I not just make linker script the second I saw that you had
> replied??

:-)

Linker scripts can do an awful lot, including this. But for your case,
this linker line suffices, in minimalist form:

__stack = 0x742 ;   /* Or whatever */

My other post discusses various ways to multiplex that with make.

The existing .init code will then use the value which you have set.
Job done.

> I just removed ,init1 & .init2 from the linker script and replaced it
> with my own code in a new section.

That's not a really good idea. They're standard sections, the compiler
wants to put the default initialisation code in there. And you can use
that code as is. If empty, the sections are simply omitted. (You have
seen that crttn13.o only has two of the ten.)

> Only small thing is, that if my code:
> ================================================================
> void init(void)  __attribute__((naked)) __attribute__((section
> (".nkinit")));
> 
> void init(void)
> {
>     __asm volatile ("     eor r1, r1\n"
>                   "       out 0x3f, r1");
> }
> ================================================================
> does not actually exist (e.g. comment it out, the linker does not throw
> any kind of error (not even an incomprehensible one!!), the code is, of
> course, missing from the output.

It is not an error for an input section to be empty. You probaly have
more than half of .init0 - .init9 empty. What you've done is quite
normal, except that it is much easier to place it in one of the existing
.init sections. e.g. If you have a hardware init for a peripheral chip,
and one for some code which uses it, you might put the former in .init3
and the latter in .init4, to make sure the execute in the right order.
(Can't think of a better example at this hour.)

If both go in the same section, link order of the separate .o files
determines execution order. That's easier to inadvertently muck up..

> Any idea how to error-trap this & make the linker throw up ??

But there is no error. You've done nothing erroneous. Ld doesn't care
whether there's anything in the input section. That's why removing the
input sections from the linker script accomplishes nothing other than
raise the risk that you might try to put something in it tomorrow. Then
you'll have an error.

> Linker script snippet is:
> ================================================================
>     /* From this point on, we don't bother about wether the insns are
>        below or above the 16 bits boundary.  */
>     *(.init0)  /* Start here after reset.  */
>     KEEP (*(.init0)) */
>     *(.nkinit)
>     KEEP (*(.nkinit))
>     /* *(.init1) */
>     /* KEEP (*(.init1))
>     /* *(.init2)  /* Clear __zero_reg__, set up stack pointer.  */
>     /* KEEP (*(.init2)) */
>     *(.init3)
>     KEEP (*(.init3))
> ================================================================

> BTW, I admit I don't know what KEEP means (manpage && google doesnt help
> either).

KEEP means this:
   Mark sections not to be eliminated, as is often useful when link-time
   garbage collection is in use. (Have a look at `--gc-sections')

Moving your stack can be done with one line of C, assembler, linker
script, or one command line -D. All the extra effort is educational, but
not actually required. ;-)

Erik



reply via email to

[Prev in Thread] Current Thread [Next in Thread]