# It appears that I need two main() functions

I am putting together a simple bootloader for the atmega8, mostly using code examples form libc's documentation. The bootloader is supposed to be located in the bootloader section of the flash. An application at the lower address needs to call the bootloader.

makefile:

LDFLAGS   += -Wl,--section-start=.text=\$(BOOTLOAD)
LDFLAGS   += -Wl,--section-start=.test=0


test.c:

__attribute__ ((section (".test"))) int main(int argc, char **argv)
{
usart_init();

send_block(sizeof(msg), msg);
_delay_ms(3000);

typedef void (* fn_ptr_t) (void);
fn_ptr_t my_ptr = (void *)0x1800;
my_ptr();
}


But I wouldn't be able to link bootloader.o and test.o into a single .hex file, because main() is duplicated.

Where should actually main() be located? And how would the other program (because, logically, those are two separate programs - application and bootloader) run?

Once more, the idea is that a small application 'test' is installed at flash address 0, together with the bootloader in the higher flash. On power-up, the application jumps to the bootloader, the user uploads his actual application, which in turn must take care to call the bootloader at appropriate times.

Actually, the very document that I link under my question is described how what I describe cannot be called a bootloader. Here is my use case. This is a small home-brew application - I doubt I will ever distribute the device to anyone. For my PCB, I can either add an ISP header (5 additional messy wires) or program the device via the same channel that I use for debugging - serial connection. I don't even have a jtag and am debugging entirely via printf() calls. This being said, if the need arises someday, it should be easy to call the well tested "bootloader" in some other way

• Looks like FAQ#7 here answers my question. I can't use the first approach, so shall try the second. We do not combine the object files, but the hex files. – Vorac Nov 1 '15 at 8:40
• "the user uploads his actual application, which in turn must take care to call the bootloader at appropriate times" This doesn't make any sense. When uploading the application, it can't execute. When done uploading, why would it need to call the bootloader for? – Lundin Nov 3 '15 at 7:31
• The idea is to have a command parser inside the application. If it reads from the uart the command for update, it jumps to the bootloader. Is silly, sure, but the simplest that I can think of. – Vorac Nov 3 '15 at 7:56
• Ok then it is just a single call from which you won't return (bootloader will reset the CPU when done). Sounded like you would repeatedly call the bootloader for some reason. – Lundin Nov 3 '15 at 10:13

Well, unless you are trying to do something really weird, generally the bootloader and application will be two entirely separate programs, each compiled to its own bin/hex file. The application would be compiled with .text=0, and the bootloader would be compiled with .text set to the beginning of the boot section. Note that this information must be passed to the linker, not the compiler. You can combine the hex files later for ease of flashing, but this is not required. If you need communication between the two, then you will have to implement a jump table or similar. You really don't have much space on an atmega8, though.

• Because I intend for the only way to run the bootloader to be a call from the application, I am adding this small "test" application in order to access the bootloader for the first time. – Vorac Nov 1 '15 at 8:35
• @Vorac - What will you do when the application has called your boot loader and the reprogramming of the replacement app is interrupted by an error or sudden loss of power? You could end up with the application area erased or only partially re-programmed. I suggest that you seriously reconsider the methods that you support for getting into your boot loader. A robust boot loader design always goes to the boot loader first and then it checks some things and may then start the application or stay in boot loader mode to support application programming. (continued) – Michael Karas Nov 1 '15 at 11:04
• (continued from above) Note that there is no problem having the application support an invocation of the boot loader but such entry needs to be prepared for recovery if something goes wrong. – Michael Karas Nov 1 '15 at 11:09
• @Vorac - You wrote " I intend for the only way to run the bootloader to be a call from the application". Please add new/extra information to your question. What you are describing is not a traditional bootloader. Most of the community will have the same understanding as Michael Karas, and for the same reasons. – gbulmer Nov 1 '15 at 15:07
• @gbulmer, indedd, and in the very document that I link under my question is described how what I describe cannot be called a bootloader. Here is my use case. This is a small home-brew application - I doubt I will ever distribute the device to anyone. For my PCB, I can either add an ISP header (5 additional messy wires) or program the device via the same channel that I use for debugging - serial connection. I don't even have a jtag and am debugging entirely via printf() calls. This being said, if the need arises someday, it should be easy to call the well tested "bootloader" in some other way – Vorac Nov 1 '15 at 19:55

Looks like FAQ#7 here answers my question. I can't use the first approach, so shall try the second. We do not combine the object files, but the hex files.

srec_cat app.hex -I boot.hex -I -o combined.hex -I


On another note, FAQ #9 explains, as Alex already mentioned, that what I am doing cannot really be called a bootloader, because it lacks the robustness of an unchanging program, being able to program the flash irrespectively of the state of the application program.