On a Leonardo, is the bootloader loaded with the sketch?

The subject line sort of says it all, but in case it's not clear, I posit that one of two things must be true:

1. When you compile a sketch for Leonardo, the compiler mixes in the bootloader to create the .hex file for uploading.

2. When you compile a sketch for Leonardo, the resulting .hex file lacks a bootloader, but the target addresses are chosen such that uploading the .hex file doesn't touch the resident bootloader.

So:

If #1 is true, where are the sources for the bootloader? It should turn up in the underlying makefile somewhere, true?

If #2 is true, is there a something that shows the memory layout?

Why am I asking this?

I'm working on a project where an Ubuntu host processor, connected to the Leonardo vis USB, needs to compile and upload a sketch from time to time.

I can program the Leonardo using the Arduino IDE (on my Mac) using the ISP port. When I plug the Leonardo into the Ubuntu host's USB port, I see /dev/ttyACM0 as expected. Then I can compile and download a sketch to the Leonardo using the Ubuntu host's USB port.

But after that, the bootloader seems to be borked, as evidenced by the fact that /dev/ttyACM0 no longer appears. This makes me think that whatever I'm loading into the Leonardo via the USB port either lacks the correct bootloader (#1) or is somehow stepping on the resident bootloader (#2).

So my real question should be:

I want to compile a sketch on an Ubuntu host and load it onto a Leonardo via USB (all without the Arduino IDE, of course). How do I make sure the resulting code in the Leonardo has a good bootloader?

2 is closer to reality. A sketch always gets uploading into low memory, near address 0. The bootloader is at the top of memory. After the bootloader is written via ISP programming, the bootloader area of memory is set to protected with the lock bits, which is a special fuse. So the bootloader is not overwritten by a USB upload, ever.

A Leonardo is somewhat special, in that the Arduino core includes with the sketch compilation a stub of code that runs the USB device in the background of the sketch, even if the sketch does not use Serial, and the purpose of the code is to listen on the USB port for a baud rate change request of 1200 baud from the IDE. That request is used to make the MCU restart and run the bootloader. It is the IDE's way of doing an auto reset without the need for bringing the reset line of the MCU low. If you are familiar with other Arduinos such as Uno, the reset on those is done by the separate USB to serial chip bringing the DTR line low and the MCU is then reset from that external connection to the reset pin. So, this means the Leonardo is particularly dependent on the running sketch containing that piece of the Arduino core to listen for that reset request from the IDE. On an Uno, all the work of running the USB port and dealing with auto reset to run the bootloader is offloaded to an external USB-to-serial chip.

So, your idea of compiling a sketch on Linux and load it without the IDE is going to be somewhat troublesome, since you need to compile using the Arduino core and not just compile pure AVR code and upload it, which would only work for the first upload. If you manually reset the MCU, or via some sort of I/O line momentarily bring the reset pin low, it will run the bootloader and you should be able to upload a second and subsequent times.

It sounds like you're doing some complex stuff, and the Leonardo is particularly complex and finicky for using in an application such as that. The bottom line is: Leonardos are a bit weird.

rdpoor: If #2 is true, is there a something that shows the memory layout?

Yes, the ATmega32U4 data sheet has an explanation and diagram of the memory layout. Chapter 27, Boot Loader Support.