Force xc32-ld to place all application code in kseg0_boot_mem
The C compiler will place the C-runtime startup code in the kseg0_boot_mem, which sets up the stack, heap, and general processor initialization.  The amount of code placed in kseg0_boot_mem will vary between a debug and release build.  If I recall correctly, when I was working on a bootloader for a PIC32MX250F, the debug build took up ~70% of the kseg0_boot_mem, which wasn't enough for my bootloader.

If your bootloader is small enough to fit into the kseg0_boot_mem along with the C startup code, reduce the size of the kseg0_boot_mem, and then relocate kseg0_program_mem to above the new boot_mem space. Note that you cannot move the starting location of the kseg0_boot_mem space. Code excecution starts at 0xBFC00000 on the PIC32, and there is nothing you can do to change that.  If you want to move the entire bootloader, you will also have to move the ISR table. For example:

MEMORY
{
  kseg0_program_mem    (rx)  : ORIGIN = 0xBFC01200, LENGTH = 0x1DF0 /* kseg1_boot is 2FF0 long.*/ 
  kseg0_boot_mem             : ORIGIN = 0x9FC00000, LENGTH = 0x1000 /* This memory region is dummy */ 
  exception_mem              : ORIGIN = 0xBFC01000, LENGTH = 0x200 /* Relocated ISR table. */
  config3                    : ORIGIN = 0xBFC02FF0, LENGTH = 0x4
  config2                    : ORIGIN = 0xBFC02FF4, LENGTH = 0x4
  config1                    : ORIGIN = 0xBFC02FF8, LENGTH = 0x4
  config0                    : ORIGIN = 0xBFC02FFC, LENGTH = 0x4
  kseg1_boot_mem             : ORIGIN = 0xBFC00000, LENGTH = 0x1000 /*This has been reduced in size.  Was 0x2FF0*/

  kseg1_data_mem       (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x8000
  sfrs                       : ORIGIN = 0xBF800000, LENGTH = 0x100000
  debug_exec_mem             : ORIGIN = 0xBFC02000, LENGTH = 0xFF0
  configsfrs                 : ORIGIN = 0xBFC02FF0, LENGTH = 0x10
}


NOTE: this is just a sample bootloader script, and should in no way be copy-pasted into production!

With that said, I can speak from experience that trying to cram a non-trivial bootloader into the boot_mem program space does not work out.  The space left over from the C startup code usually is not enough, particularly if you want some heavy error-handling and validation (and yes, you DO want this!).  Removing the debug builds from the very limited arsenal of embedded debug tools is not good either.  You will need to be able to debug on hardware at some point in the future.  I learned that lesson the hard way.

My recommendation is to leave the kseg0_boot_mem code section alone, and just work with the kseg0_program_mem space.  Grab a slice of the kseg0_program_mem at the top or bottom (doesn't matter) and use that for your bootloader code and ISR table.  Leave yourself some room for bootloader code growth as well.  Dealing with multiple linker scripts is a bit of pain.