AT32 UC3 Writing a bootloader from scratch

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi there,

 

my task is to write a new bootloader for our UC3 chip, and Im already stuck getting to "main"... My requirements:

1.write a minimal linker script

2.init stuff in a boot.S file (load init data, setup stack, I guess)

3.from there jump to main function, hoping I can use C and ASF wizard now

 

my problems, dunno which to solve first:

1. I looked deep into gcc-ld's man page and I understand how I can define sections now, but I have no idea, which sections I even need

f.e. there it shows the linker script could be as simple as:

SECTIONS
{
. = 0x8000000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}

but this does no initialization, atmel throws a million errors for missing symbols and some example script ive found has WAY too much things in it for me to grasp: https://pastebin.com/VKTiDWLH

can someone help me writing a "minimal" script that still contains stack and shit, so the C code can work with it?

2. boot.S is another beast, but if I understand it right, it just copied the constant values and jumps to main, right? if I debug the result, it jumps SOMEWHERE but not main (says no source file) my current file: https://pastebin.com/zW5w25AJ

3. I tried to create an new gcc c executable project, tried to open asf wizard so it sees the board defines are missing and adds them. I then can add asf libs and the entire thing compiles, BUT, theres no linker script, at the reset vector is only a trampoline, not my boot.s and the all the real code is at 0x80002000+ , so exactly where I DONT wanna have it, obviously these 0x2000 bytes are my entire space for the bootloader (maybe more if needed, but wanna keep it small). if I add the option  -Wl,-Ttext=0x80000000 it tries to move code there but has overlapping problems with other sections again...

4. I would love to compile without "optimizations", aka not remove unused functions and sections (so I rather minimize my code instead), if I do this, it always says something like "cant fit section XXXX into FLASH, overlap by soAndSoMany bytes"

 

 

so

 

 

How the hell is someone supposed to get started with this?!? by the time I understand every details in the script and asm, ive written the entire thing in assembler and create my own toolchain or what? are there manuals or tutorials for this? anything official? a minimal project? all "example" bootloaders ive seen are for 8bit, so no use for me. avr's own ISP bootloader is pretty big, id be happy if I get to the point when I can just start setting up clocks in C...

 

HELP, PLEASE!

 

greetz

Last Edited: Wed. Jan 24, 2018 - 07:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have to start by saying that I know nothing at all about UC3 but I will describe the situation with AVR8 (tiny/mega) and perhaps you will spot something similar? (I assume the AVR32-UC3 inherited some aspects of AVR8??)

 

For AVR8 the location from which the AVR makes its first opcode fetch at power on is selectable. There is a fuse called BOOTRST and if it is active it says "start execution at some fixed address not 0x0000". Normally first fetch is from 0x0000. So the only "trick" to writing a bootloader for AVR8 (and that can include a complete C program - no need to do anything particularly special and certainly no need for linker script changes) is simply to say to the build "I want this whole thing located from address 0xNNNN upwards" rather than the 0x0000 you would usually default to. To this it's simply a case of passing the linker command:

-Wl,-Ttext=0x1234

replacing 0x1234 with the actual entry point address. Now you just build this C program as usual but the whole thing (reset entry point, interrupt vectors, C Run Time, code from main() onwards) is all lifted bodily and placed from 0x1234 onwards rather than 0x0000 onwards that it would otherwise default to.

 

So isn't UC3 similar? Does it have some special fixed entry point (not the normal address) that is used when it's configured in some way to say "start in bootloader not at the normal app address". If so then surely the solution is the same and you just -Ttext=0x1234 to bodily move the entire C program you write to that new entry point?

 

EDIT: just tried searching/googling but everything I find about AVR32 bootloaders leads to "DFU" so is there some reason not to use DFU?

Last Edited: Wed. Jan 24, 2018 - 02:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

clawson wrote:
EDIT: just tried searching/googling but everything I find about AVR32 bootloaders leads to "DFU" so is there some reason not to use DFU?

 

yes, id like to have full control over what comes out, I wrote a cheap hack of the DFU project, but thats far from satisfying, after some more trial and error I found a nice way to do this (with the stuff I already had)

 

1. so yes, start with making a new gcc c project

2. open asf wizard, which complains over missing board defs, so let it add that (select UC3 board template)

3. now you have 2 "main.c" files, delete the old one (you can also add asf stuff with the wizard now)

4. removed trampoline.S and .h

5. my new startup.S is now https://pastebin.com/H2CwTZQR so now its at the very start of my code at 0x80000000

6. add a file under "config" folder, call it "linker.lds" f.e., here my "minimal" version https://pastebin.com/h1aDgFZG (.HWparams can be removed, is just for my settings)

7. in project settings -> linker -> misc, replace the line linker flags with "-T../src/conf/linker.lds"

 

this should compile now, I tested it and I can successfully step from asm in startup.s into C of main.c and continue stepping through functions, so I think I solved this one, thanks for your input anyway :D

 

greetz

 

PS: a nice tool to debug which sections are not needed is objdump with -t or -h : https://pastebin.com/enqnrJAy (symbol table) and https://pastebin.com/SLKf6eWQ (section headers)

PPS: for reference, the ld manual https://www.eecs.umich.edu/cours...

Last Edited: Wed. Jan 24, 2018 - 02:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

warrantyvoider wrote:
4. removed trampoline.S and .h

5. my new startup.S is now https://pastebin.com/H2CwTZQR so now its at the very start of my code at 0x80000000

6. add a file under "config" folder, call it "linker.lds" f.e., 

But why is all that required if the goal is simply to move the execution entry point to 0x80000000. Why isn't it as simple as just -Ttext=0x80000000 ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

well, mutiple things and im no expert either, but heres what I think/know

 

trampoline.S is really just a jump, because the reset vector is always 0x80000000, so for normal apps and any that gets started by a bootloader, the actual code can be far beyond the trampoline, usually starts at 0x80002000. now I removed that, because I ofc wanted my actual bootcode to be there ".section  .reset, "ax", @progbits" does exactly that, because there is a section defined with the name ".reset".

now I told you, I already tried the -Ttext switch and it doesnt like it, I can only guess here as I dont see where the "default" (maybe internal) linker script is and whats written in it, but I guess either

a) the other sections have hardcoded offsets, not relative, thus only moving the single ".text" section doesnt move the others, thus overlaps or

b) theres also regions! if you define a section that is in none of the defined regions, it wont know where to put it...

either way, im not sure and just happy this works for now :D

 

greetz

Last Edited: Wed. Jan 24, 2018 - 03:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I dunno if this is usefull / related, I'll leave that up to you:

 

Some time ago I looked into STM32F103 (So different chip manutacturer, architecture etc, but also based on a GCC version).

Then I found a tutorial (for stm32) made by "pandafruits". A very small, but compact and informational intro about getting started with STM32 inclusive writing linker scripts.

 

http://pandafruits.com/stm32_pri...

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

nice, thanks! its related and useful! the only problem is atmel may use some special section names, like .heap and .stack, also the "PROVIDE" command generates symbol names that are used in ASF, but overall this is a nice overview on how to prepare a toolchain :D

 

greetz

Last Edited: Wed. Jan 24, 2018 - 05:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey warrantyvoider. I have no personal experience writing bootloaders for the UC3 and I don't understand all the detail of what you're discussing. However, the previous engineers at my company did write a custom bootloader (actually several different versions) that is used in all our products.

 

It's definitely NOT a minimal example, but if you need some pointers then I'm happy to share what they wrote. Maybe not publicly though - PM/email might be better. Let me know :)

 

Also,

warrantyvoider wrote:
atmel may use some special section names, like .heap and .stack
I'm not sure if you're asking about this, or stating it as an example but yes, our linker script does mention both these names.

Last Edited: Thu. Jan 25, 2018 - 03:19 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

warrantyvoider wrote:
are there manuals or tutorials for this? anything official?
The UC3C USB DFU bootloader app note has a manual and a zip (bootloaders without source code); source code is apparently in ASF.

 

Microchip Technology Inc

Microchip

AN_32166

AVR32806: AVR UC3 USB DFU Boot Loader, Version 1.1.0 and Higher

http://www.microchip.com//wwwAppNotes/AppNotes.aspx?appnote=en591315

via http://www.microchip.com/wwwproducts/en/at32uc3c2512c

Please be patient (several minutes) with the following URL (artifact of atmel.com retirement?)

http://asf.atmel.com/docs/latest/common.services.usb.class.dfu_atmel.device.bootloader.avr32.uc3c/html/index.html

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ConnectSaucer wrote:
It's definitely NOT a minimal example, but if you need some pointers then I'm happy to share what they wrote. Maybe not publicly though - PM/email might be better. Let me know :)

 

thanks alot for the offer, but I think I got it going now. also id like to leave the solutions for others to read

 

gchapman wrote:
The UC3C USB DFU bootloader app note has a manual and a zip (bootloaders without source code); source code is apparently in ASF.

 

thats the example bootloader I was talking about, thanks for the links. if you look into the pdf it says:

 

essentially explaining the removing of the trampoline that I did, and it doesnt explain how the linker scripts work, only to "choose one existing" (havent found out where those are on my pc yet) and the screenshot of the linker menu is, well, slightly outdated...

 

 

greetz

Last Edited: Thu. Jan 25, 2018 - 07:27 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I noticed that my constant and initialized data was missing/zero (aka when you do f.e. static const U8 array[] = {1,2,3,4} the data 01 02 03 04 has to written into its position in RAM, but if you checked it with a debugger, its missing/zero) so I found out that I forgot the initializing function in the boot asm, so here the fixed version

 

https://pastebin.com/nux3tDv4

 

greetz