OTA update - sodaq board (arduino M0 compatible)
SOLVED!
I have compiled my own SDUBoot.ino with fixed SDU_START 0x2000 and for SODAQ Sara (boot/sodaq_sara.h). My sketch with #include &quot;SDU.h&quot; compiles successfully. The board package is also installed in Arduino (http://downloads.sodaq.net/package_sodaq_samd_index.json). Here my code with changes (base is SodaqCore-samd-1.8.6-sodaq from Github):
File libraries/SDU/extras/SDUBoot/SDUBoot.ino:
#include &lt;SD.h&gt;
#include &lt;FlashStorage.h&gt;

#define SDU_START    0x2000
#define SDU_SIZE     0x4000

#define SKETCH_START (uint32_t*)(SDU_START + SDU_SIZE)

#ifndef SDCARD_SS_PIN
#define SDCARD_SS_PIN 10
#endif

#define UPDATE_FILE &quot;UPDATE.BIN&quot;

FlashClass flash;

// Initialize C library
extern &quot;C&quot; void __libc_init_array(void);

int main() {
  init();

  __libc_init_array();

  delay(1);

  if (SD.begin(SDCARD_SS_PIN) &amp;&amp; SD.exists(UPDATE_FILE)) {
    File updateFile = SD.open(UPDATE_FILE);
    uint32_t updateSize = updateFile.size();
    bool updateFlashed = false;

    if (updateSize &gt; SDU_SIZE) {
      // skip the SDU section
      updateFile.seek(SDU_SIZE);
      updateSize -= SDU_SIZE;

      uint32_t flashAddress = (uint32_t)SKETCH_START;

      // erase the pages
      flash.erase((void*)flashAddress, updateSize);

      uint8_t buffer[512];

      // write the pages
      for (uint32_t i = 0; i &lt; updateSize; i += sizeof(buffer)) {
        updateFile.read(buffer, sizeof(buffer));

        flash.write((void*)flashAddress, buffer, sizeof(buffer));

        flashAddress += sizeof(buffer);
      }

      updateFlashed = true;
    }

    updateFile.close();

    if (updateFlashed) {
      SD.remove(UPDATE_FILE);
    }
  }

  // jump to the sketch
  __set_MSP(*SKETCH_START);

  //Reset vector table address
  SCB-&gt;VTOR = ((uint32_t)(SKETCH_START) &amp; SCB_VTOR_TBLOFF_Msk);

  // address of Reset_Handler is written by the linker at the beginning of the .text section (see linker script)
  uint32_t resetHandlerAddress = (uint32_t) * (SKETCH_START + 1);
  // jump to reset handler
  asm(&quot;bx %0&quot;::&quot;r&quot;(resetHandlerAddress));
}

File libraries/SDU/extras/SDUBoot/build.sh:
#!/bin/sh -x

ARDUINO=arduino
SKETCH_NAME=&quot;SDUBoot.ino&quot;
SKETCH=&quot;$PWD/$SKETCH_NAME&quot;
BUILD_PATH=&quot;$PWD/build&quot;
OUTPUT_PATH=&quot;../../src/boot&quot;

if [[ &quot;$OSTYPE&quot; == &quot;darwin&quot;* ]]; then
    ARDUINO=&quot;/Applications/Arduino.app/Contents/MacOS/Arduino&quot;
fi

buildSDUBootSketch() {
    BOARD=$1
    DESTINATION=$2

    $ARDUINO --verify --board $BOARD --preserve-temp-files --pref build.path=&quot;$BUILD_PATH&quot; $SKETCH
    cat &quot;$BUILD_PATH/$SKETCH_NAME.bin&quot; | xxd -i &gt; $DESTINATION
    rm -rf &quot;$BUILD_PATH&quot;
}

mkdir -p &quot;$OUTPUT_PATH&quot;

buildSDUBootSketch &quot;SODAQ:samd:sodaq_sara&quot; &quot;$OUTPUT_PATH/sodaq_sara.h&quot;

File libraries/SDU/src/SDU.cpp:
#include &lt;Arduino.h&gt;

#include &quot;SDU.h&quot;

__attribute__ ((section(&quot;.sketch_boot&quot;)))
unsigned char sduBoot[0x4000] = {
  #include &quot;boot/sodaq_sara.h&quot;
};

Sketch file sdu_test.ino:
#include &lt;Arduino.h&gt;
#include &quot;SDU.h&quot;

#if defined(ARDUINO_SODAQ_SARA)
#define DEBUG_STREAM SerialUSB
#else
#error &quot;Please select the SODAQ SARA as your board&quot;
#endif

#define DEBUG_STREAM_BAUD 115200

String message;

void setup() {
  // Start communication.
  DEBUG_STREAM.begin(DEBUG_STREAM_BAUD);

  while (!DEBUG_STREAM) {
    // Wait for Serial Monitor to be opened.
  }

  message += &quot;Sketch compile date and time: &quot;;
  message += __DATE__;
  message += &quot; &quot;;
  message += __TIME__;

  // print out the sketch compile date and time on the serial port
  DEBUG_STREAM.println(message);
}

void loop() {
  // add you own code here
}

File arduino/50/.arduino15/packages/SODAQ/hardware/samd/1.8.6/variants/sodaq_sara/linker_scripts/gcc/flash_with_bootloader.ld add these lines:
KEEP(*(.sketch_boot))

. = ALIGN(0x2000);

here:
...
SECTIONS
{
    PROVIDE(__sodaq_firmware_state = ORIGIN(FLASH) - 0x100);

    .text :
    {
        __text_start__ = .;

        KEEP(*(.sketch_boot))

        . = ALIGN(0x2000);
        KEEP(*(.isr_vector))
        ...

On SD card (formatted as FAT32) I have stored the renamed file UPDATE.bin without bootloader of the compiled sketch file. Pin D10 is connected and used as chip select CS.
Build boot hex files:
$ cd libraries/SDU/extras/SDUBoot
$ ./build.sh

Version 1.8.6-sodaq has these missing lines on arduino_zero variant but not on sodaq_sara variant.