In Table 30-7 of the ATMega328P datasheet, it says that with BOOTSZ1 and BOOTSZ0 both programmed to 0, the start of the bootloader secion is 0x3800.
I tried using this address for the start of the .text section as discussed here:
But it didn't work (after concatenating bootloader and application programs as described elsewhere in that FAQ, and programming fuses as required).
I took a look in the optiboot .hex file provided with Arduino and see that the first address for that bootloader seems to be 0x7800. I tried that instead, concatenate and sure enough bootloader and main app then both work as expected.
I though maybe word vs byte address or something (but mega is 8 bit so what's the difference?), but 0x7800 != 2 * 0x3800, so I have no more ideas. What's going on here?