EmbDev.net

Forum: ARM programming with GCC/GNU tools Bootloader allocation via link script: wizardy?


von Nils S. (nilswed)


Attached files:

Rate this post
useful
not useful
Howdy,
using James Lynch (thanks for all your work!) script as base, I am
trying to link a bootloader I wrote to address 0x18000 in flash area.
All I get is
arm-elf-ld:linkconfig_FLASH.cmd:126: syntax error script error
which doesn't help a bit!
Can anyone please tell me where I am wrong?
The script is attached!
Thanks in any case for reading this epistle!
Nils

von Nils S. (nilswed)


Rate this post
useful
not useful
Nils Soderman wrote:

Trying some more, reading the ld manual for the fifties time, Ican link
with this part changed from the attached file (with all comments
removed...):

/* now define the output sections  */
SECTIONS
{
  . = 0;  /* set location counter to address zero  */
  .text :
  {
    *(.text)
    *(.rodata)
    *(.rodata*)
    *(.glue_7)
    *(.glue_7t)
    _etext = .;
  } >flash

  bootloader 0x18000 :
    {
    bootloader.o *(.bootloader)
    -ebootloader = .;
  } >flash

  .data :
  {
    _data = .;
    *(.data)
    _edata = .;
  } >ram AT >flash

This variant loads bootloader code to 0x18000 (at last!) AND to address
0!!
So how do I remove bootloader from the .text part???

(*(EXCLUDE_FILE (*bootloader.o) .text))  //As per manual!

gives link script error.
I also get the errors:
arm-elf-ld: address 0x275e0 of main.out section bootloader is not within
region flash
arm-elf-ld: section .text [00000000 -> 000158f7] overlaps section .data
[00000000 -> 00000027]
Any wizard on link scripts willing to give me a hint?
Must I compile bootloader.c separately?
Hopefully waiting
Nils

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
Nils Soderman wrote:
>...
>   bootloader 0x18000 :
>     {
>     bootloader.o *(.bootloader)

Did you use a section attribute for the functions in bootloader.c? If
not you may try bootloader.o(.text .text.*).

>     -ebootloader = .;
>   } >flash

Maybe you can try with a extra memory-region for this so there is not
just "flash" and "ram" but also for example "boot" where boot has the
origin 0x18000. So you don't need the "0x18000" somewhere else and just
just ">boot" instead of ">flash" at the end of the linker-section entry.

> This variant loads bootloader code to 0x18000 (at last!) AND to address
> 0!!
> So how do I remove bootloader from the .text part???
>
> (*(EXCLUDE_FILE (*bootloader.o) .text))  //As per manual!

Again. Did you use section attributes? It's difficult to help just by
looking on the linker-scripts.

> gives link script error.

Exact error message?

> I also get the errors:
> arm-elf-ld: address 0x275e0 of main.out section bootloader is not within
> region flash
> arm-elf-ld: section .text [00000000 -> 000158f7] overlaps section .data
> [00000000 -> 00000027]
> Any wizard on link scripts willing to give me a hint?

I'm not a wizard in this field but maybe I can help. Create the minimal
example with all needed files for a "make all" pack it into a
zip-archive and attach it to a message.

> Must I compile bootloader.c separately?
I don't think this is a "must".

von Nils S. (nilswed)


Attached files:

Rate this post
useful
not useful
Martin Thomas wrote:
> Nils Soderman wrote:
>>...
>>   bootloader 0x18000 :
>>     {
>>     bootloader.o *(.bootloader)
>
> Did you use a section attribute for the functions in bootloader.c? If
> not you may try bootloader.o(.text .text.*).
>
>>     -ebootloader = .;
>>   } >flash
>
> Maybe you can try with a extra memory-region for this so there is not
> just "flash" and "ram" but also for example "boot" where boot has the
> origin 0x18000. So you don't need the "0x18000" somewhere else and just
> just ">boot" instead of ">flash" at the end of the linker-section entry.
>
>> This variant loads bootloader code to 0x18000 (at last!) AND to address
>> 0!!
>> So how do I remove bootloader from the .text part???
>>
>> (*(EXCLUDE_FILE (*bootloader.o) .text))  //As per manual!
>
> Again. Did you use section attributes? It's difficult to help just by
> looking on the linker-scripts.
>
>> gives link script error.
>
> Exact error message?
>
>> I also get the errors:
>> arm-elf-ld: address 0x275e0 of main.out section bootloader is not within
>> region flash
>> arm-elf-ld: section .text [00000000 -> 000158f7] overlaps section .data
>> [00000000 -> 00000027]
>> Any wizard on link scripts willing to give me a hint?
>
> I'm not a wizard in this field but maybe I can help. Create the minimal
> example with all needed files for a "make all" pack it into a
> zip-archive and attach it to a message.
>
>> Must I compile bootloader.c separately?
> I don't think this is a "must".

Thanks Martin!
I followed your suggestion and made a mini application!
My application is a open source project for radio amateurs in
Scandinavia, Germany and Great Britain. (See webpage www.QROlle.se!)They
must be able to reprogram the firmware easily at their home. My idea is
to, with the first firmware, supply a bootloader with address 0x18000.
This loader will stay there permanently. When they press a certain
button after reset, the software will jump to the bootloader, waiting
for serial communication from a PC with the new firmware, programming
the flash with it. This firmware is NOT supposed to overwrite the
bootloader.
So this is my scenario, will it work?
You are writing about section attributes, things I know nothing about. I
will try to find info abt it on the gcc homepage! I have been wondering
how to link parts of a software to a certain address in C language, it
is easier in assembler! Must it be done in the link script for C
programs???
Lets see if what I have been writing here can help to tell me what to
do!
With best regards
Nils

von Nils S. (nilswed)


Rate this post
useful
not useful
Nils Soderman wrote:
> Martin Thomas wrote:
>> Nils Soderman wrote:
>>>...
>>>   bootloader 0x18000 :
>>>     {
>>>     bootloader.o *(.bootloader)
>>
>> Did you use a section attribute for the functions in bootloader.c? If
>> not you may try bootloader.o(.text .text.*).
>>
>>>     -ebootloader = .;
>>>   } >flash
>>
>> Maybe you can try with a extra memory-region for this so there is not
>> just "flash" and "ram" but also for example "boot" where boot has the
>> origin 0x18000. So you don't need the "0x18000" somewhere else and just
>> just ">boot" instead of ">flash" at the end of the linker-section entry.
>>
>>> This variant loads bootloader code to 0x18000 (at last!) AND to address
>>> 0!!
>>> So how do I remove bootloader from the .text part???
>>>
>>> (*(EXCLUDE_FILE (*bootloader.o) .text))  //As per manual!
>>
>> Again. Did you use section attributes? It's difficult to help just by
>> looking on the linker-scripts.
>>
>>> gives link script error.
>>
>> Exact error message?
>>
>>> I also get the errors:
>>> arm-elf-ld: address 0x275e0 of main.out section bootloader is not within
>>> region flash
>>> arm-elf-ld: section .text [00000000 -> 000158f7] overlaps section .data
>>> [00000000 -> 00000027]
>>> Any wizard on link scripts willing to give me a hint?
>>
>> I'm not a wizard in this field but maybe I can help. Create the minimal
>> example with all needed files for a "make all" pack it into a
>> zip-archive and attach it to a message.
>>
>>> Must I compile bootloader.c separately?
>> I don't think this is a "must".
>
> Thanks Martin!
> I followed your suggestion and made a mini application!
> My application is a open source project for radio amateurs in
> Scandinavia, Germany and Great Britain. (See webpage www.QROlle.se!)They
> must be able to reprogram the firmware easily at their home. My idea is
> to, with the first firmware, supply a bootloader with address 0x18000.
> This loader will stay there permanently. When they press a certain
> button after reset, the software will jump to the bootloader, waiting
> for serial communication from a PC with the new firmware, programming
> the flash with it. This firmware is NOT supposed to overwrite the
> bootloader.
> So this is my scenario, will it work?
> You are writing about section attributes, things I know nothing about. I
> will try to find info abt it on the gcc homepage! I have been wondering
> how to link parts of a software to a certain address in C language, it
> is easier in assembler! Must it be done in the link script for C
> programs???
> Lets see if what I have been writing here can help to tell me what to
> do!
> With best regards
> Nils

Have been trying with attribute keyword:
Declaration in bootloader.c:
UINT bootloader(void) _attribute_ ((section ("BOOT")));

UINT bootloader(void)
{
return 0;
  };

linker error:
arm-elf-ld: error: no memory region specified for loadable section
`BOOT'

Link script part:

SECTIONS
{

  . = 0;

  .text :
  {
    *(.text)
    *(.rodata)
    *(.rodata*)
    *(.glue_7)
    *(.glue_7t)
  } >flash

       . = 0x18000;

  .BOOT :
  {
    *(.BOOT)
    _etext = .;
  } >flash

How do I specify memory region? I thought I did with ">flash" !

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
Nils Soderman wrote:
> I followed your suggestion and made a mini application!
A little too mini. No startup-code. Also: do not use the linker
(arm-elf-ld) directly to link the application, use the frontend
(arm-elf-gcc).

> My application is a open source project for radio amateurs in
> Scandinavia, Germany and Great Britain. (See webpage www.QROlle.se!)They
> must be able to reprogram the firmware easily at their home. My idea is
> to, with the first firmware, supply a bootloader with address 0x18000.
> This loader will stay there permanently. When they press a certain
> button after reset, the software will jump to the bootloader, waiting
> for serial communication from a PC with the new firmware, programming
> the flash with it. This firmware is NOT supposed to overwrite the
> bootloader.
> So this is my scenario, will it work?

It may work but you have to take care that every application "knows"
where the bootloader is located and how to start it or a broken
application or a failed transfer trough the bootloader may "brick" the
controller so the users have to use another method to program a "good"
application and maybe the bootloader too if something went wrong. The
bootloader-code may also use functions for the libc and/or libgcc
internally and you would have to make sure that those functions are also
located in the special memory-area.

I suggest to use another approach, it's not a new one and not my idea,
it's commonly used:

- create the bootloader as a stand alone application which is located at
address 0x0 or better said in the memory-area which is mapped to 0x0
after reset. Basically the same setup you are using to create a
stand-alone application. With this you are sure the bootloader gets
always started and does not depend on any function of the rest of the
code.

- So the bootloader-code runs first after reset end checks if the button
has been pressed (bootloader start-condition), if not pressed an
application gets started at a "well known" address. If yes the
bootloader enters "bootloading-mode" and waits for data  that to be
written to the flash-memory from the PC using some kind of protocol
(self defined or maybe something like X/Y/Z-Modem)

- the application to be programmed through the bootloader needs to be
linked to the address to which the bootloader jumps to when the button
is not pressed.

- Since interrupts will be used in the user application should use some
instructions in the startup-code for remapping and maybe copying of the
application's exception-vectors. See the startup-codes in the
AT91SAM7S-EK software-package.


> You are writing about section attributes, things I know nothing about. I
> will try to find info abt it on the gcc homepage! I have been wondering
> how to link parts of a software to a certain address in C language, it
> is easier in assembler! Must it be done in the link script for C
> programs???
There are some options that can be passed to the linker to set
start-addresses of C-sections (the ones used with the attribute). I
personally prefer the approach where everything is configured with a
linker-script so there is just one place to check/modify. You can assign
a section attribute to a c-Function or C-variable and use the
linker-script (or linker-CL-options) to let the linker assign
memory-addresses. And as you already found out there are options to
assign object-code from files to certain regions.

> Lets see if what I have been writing here can help to tell me what to
> do!
As written: create the bootloader as a "stand alone" application. Take
care about the in-application-flash-code. Some instructions needed for
in-application flash-programming need to be run from the AT91SAM7's RAM.
See the "basic-internal-flash" demo in the SAM7S-EK software package.

For initial programming you can use SAM-BA or any other
flash-programming method to flash the bootloader and then use the
bootloader to upload the first user-application. To save the the second
step during initial setup you may also merge the hex- or binary-files of
bootloader and the first application to a single load-image so just one
step is needed for flash the combined load-image.

You may find useful information of my GNU port of the STR7 V3.0
bootloader (
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index_str.html#str7_uart_boot
). Although it's not for AT91 at least the concept and parts of the code
can be re-used.

There are also at least two open-source USB-Bootloaders for AT91SAM7
from where you can "borrow" ideas. Sorry, no links but google should
find.


>...
> linker error:
> arm-elf-ld: error: no memory region specified for loadable section
> `BOOT'
>...
You have used BOOT for the section-attribute and .BOOT in the
linker-script.

But I really suggest not to continue creating the bootloader and
user-code together. Create them as separate applications. You will still
have enough work getting the in-application-flashing and the
exception-vectors remapping implemented correctly.

von Nils S. (nilswed)


Rate this post
useful
not useful
Thank You Martin!
You mentioned things I haven't taken into consideration: you are
definitely right to suggest a wellproven approach. So back to the
drawing board! So I will try to have the application start at a upper
address (above bootloader) instead. But my attempts at relocating have
so far been unsuccessful... As per your answer: I will use, if possible,
only the link script!
Now I will start studying the sourcecodes you were suggesting in your
answer.
Thanks again for your help!
Nils

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.