Can I force a function to live in the boot sector without overwriting the bootloader?
The Optiboot version 8 has a do_spm function which can be called from application. The Optiboot repository contains an example for the use of this function.
SPM is the AVR CPU instruction to write to flash memory. The Optiboot wraps this in a function. A pointer to this function is put in a 'vector table' at the beginning of the bootloader. The first pointer jumps to main, the second pointer jumps to do_spm. The optiboot.h then has the function as (version for small Optiboot)
typedef void (*do_spm_t)(uint16_t address, uint8_t command, uint16_t data);
const do_spm_t do_spm = (do_spm_t)((FLASHEND-511+2)&gt;&gt;1)

I made an enhancement of this, a copy_flash_pages function with reset option to bootload an AVR from its own flash. It is added as third entry in the 'vectors table' of Optiboot. It is used in my ArduinoOTA library for AVR MCUs.
typedef void (*copy_flash_pages_t)(uint32_t dest, uint32_t src, uint16_t page_count, uint8_t reset);
const copy_flash_pages_t copy_flash_pages = (copy_flash_pages_t)((FLASHEND-1023+4)&gt;&gt;1);