diff --git a/tools/elf2uf2/main.cpp b/tools/elf2uf2/main.cpp
new file mode 100644
index 0000000..2c0ddcd
--- /dev/null
+++ b/tools/elf2uf2/main.cpp
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cstdio>
+#include <map>
+#include <vector>
+#include <cstring>
+#include <cstdarg>
+#include <algorithm>
+#include "boot/uf2.h"
+#include "elf.h"
+
+typedef unsigned int uint;
+
+#define ERROR_ARGS -1
+#define ERROR_FORMAT -2
+#define ERROR_INCOMPATIBLE -3
+#define ERROR_READ_FAILED -4
+#define ERROR_WRITE_FAILED -5
+
+static char error_msg[512];
+static bool verbose;
+
+static int fail(int code, const char *format, ...) {
+    va_list args;
+    va_start(args, format);
+    vsnprintf(error_msg, sizeof(error_msg), format, args);
+    va_end(args);
+    return code;
+}
+
+static int fail_read_error() {
+    return fail(ERROR_READ_FAILED, "Failed to read input file");
+}
+
+static int fail_write_error() {
+    return fail(ERROR_WRITE_FAILED, "Failed to write output file");
+}
+
+// we require 256 (as this is the page size supported by the device)
+#define LOG2_PAGE_SIZE 8u
+#define PAGE_SIZE (1u << LOG2_PAGE_SIZE)
+
+struct address_range {
+    enum type {
+        CONTENTS,     // may have contents
+        NO_CONTENTS,  // must be uninitialized
+        IGNORE        // will be ignored
+    };
+    address_range(uint32_t from, uint32_t to, type type) : from(from), to(to), type(type) {}
+    address_range() : address_range(0, 0, IGNORE) {}
+    type type;
+    uint32_t to;
+    uint32_t from;
+};
+
+typedef std::vector<address_range> address_ranges;
+
+#define MAIN_RAM_START        0x20000000u
+#define MAIN_RAM_END          0x20042000u
+#define FLASH_START           0x10000000u
+#define FLASH_END             0x15000000u
+#define XIP_SRAM_START        0x15000000u
+#define XIP_SRAM_END          0x15004000u
+#define MAIN_RAM_BANKED_START 0x21000000u
+#define MAIN_RAM_BANKED_END   0x21040000u
+
+const address_ranges rp2040_address_ranges_flash {
+    address_range(FLASH_START, FLASH_END, address_range::type::CONTENTS),
+    address_range(MAIN_RAM_START, MAIN_RAM_END, address_range::type::NO_CONTENTS),
+    address_range(MAIN_RAM_BANKED_START, MAIN_RAM_BANKED_END, address_range::type::NO_CONTENTS)
+};
+
+const address_ranges rp2040_address_ranges_ram {
+    address_range(MAIN_RAM_START, MAIN_RAM_END, address_range::type::CONTENTS),
+    address_range(XIP_SRAM_START, XIP_SRAM_END, address_range::type::CONTENTS),
+    address_range(0x00000000u, 0x00004000u, address_range::type::IGNORE) // for now we ignore the bootrom if present
+};
+
+struct page_fragment {
+    page_fragment(uint32_t file_offset, uint32_t page_offset, uint32_t bytes) : file_offset(file_offset), page_offset(page_offset), bytes(bytes) {}
+    uint32_t file_offset;
+    uint32_t page_offset;
+    uint32_t bytes;
+};
+
+static int usage() {
+    fprintf(stderr, "Usage: elf2uf2 (-v) <input ELF file> <output UF2 file>\n");
+    return ERROR_ARGS;
+}
+
+static int read_and_check_elf32_header(FILE *in, elf32_header& eh_out) {
+    if (1 != fread(&eh_out, sizeof(eh_out), 1, in)) {
+        return fail(ERROR_READ_FAILED, "Unable to read ELF header");
+    }
+    if (eh_out.common.magic != ELF_MAGIC) {
+        return fail(ERROR_FORMAT, "Not an ELF file");
+    }
+    if (eh_out.common.version != 1 || eh_out.common.version2 != 1) {
+        return fail(ERROR_FORMAT, "Unrecognized ELF version");
+    }
+    if (eh_out.common.arch_class != 1 || eh_out.common.endianness != 1) {
+        return fail(ERROR_INCOMPATIBLE, "Require 32 bit little-endian ELF");
+    }
+    if (eh_out.eh_size != sizeof(struct elf32_header)) {
+        return fail(ERROR_FORMAT, "Invalid ELF32 format");
+    }
+    if (eh_out.common.machine != EM_ARM) {
+        return fail(ERROR_FORMAT, "Not an ARM executable");
+    }
+    if (eh_out.common.abi != 0) {
+        return fail(ERROR_INCOMPATIBLE, "Unrecognized ABI");
+    }
+    if (eh_out.flags & EF_ARM_ABI_FLOAT_HARD) {
+        return fail(ERROR_INCOMPATIBLE, "HARD-FLOAT not supported");
+    }
+    return 0;
+}
+
+int check_address_range(const address_ranges& valid_ranges, uint32_t addr, uint32_t vaddr, uint32_t size, bool uninitialized, address_range &ar) {
+    for(const auto& range : valid_ranges) {
+        if (range.from <= addr && range.to >= addr + size) {
+            if (range.type == address_range::type::NO_CONTENTS && !uninitialized) {
+                return fail(ERROR_INCOMPATIBLE, "ELF contains memory contents for uninitialized memory");
+            }
+            ar = range;
+            if (verbose) {
+                printf("%s segment %08x->%08x (%08x->%08x)\n", uninitialized ? "Uninitialized" : "Mapped", addr,
+                   addr + size, vaddr, vaddr+size);
+            }
+            return 0;
+        }
+    }
+    return fail(ERROR_INCOMPATIBLE, "Memory segment %08x->%08x is outside of valid address range for device", addr, addr+size);
+}
+
+int read_and_check_elf32_ph_entries(FILE *in, const elf32_header &eh, const address_ranges& valid_ranges, std::map<uint32_t, std::vector<page_fragment>>& pages) {
+    if (eh.ph_entry_size != sizeof(elf32_ph_entry)) {
+        return fail(ERROR_FORMAT, "Invalid ELF32 program header");
+    }
+    if (eh.ph_num) {
+        std::vector<elf32_ph_entry> entries(eh.ph_num);
+        if (fseek(in, eh.ph_offset, SEEK_SET)) {
+            return fail_read_error();
+        }
+        if (eh.ph_num != fread(&entries[0], sizeof(struct elf32_ph_entry), eh.ph_num, in)) {
+            return fail_read_error();
+        }
+        for(uint i=0;i<eh.ph_num;i++) {
+            elf32_ph_entry& entry = entries[i];
+            if (entry.type == PT_LOAD && entry.memsz) {
+                address_range ar;
+                int rc;
+                uint mapped_size = std::min(entry.filez, entry.memsz);
+                if (mapped_size) {
+                    rc = check_address_range(valid_ranges, entry.paddr, entry.vaddr, mapped_size, false, ar);
+                    if (rc) return rc;
+                    // we don't download uninitialized, generally it is BSS and should be zero-ed by crt0.S, or it may be COPY areas which are undefined
+                    if (ar.type != address_range::type::CONTENTS) {
+                        if (verbose) printf("  ignored\n");
+                        continue;
+                    }
+                    uint addr = entry.paddr;
+                    uint remaining = mapped_size;
+                    uint file_offset = entry.offset;
+                    while (remaining) {
+                        uint off = addr & (PAGE_SIZE - 1);
+                        uint len = std::min(remaining, PAGE_SIZE - off);
+                        auto &fragments = pages[addr - off]; // list of fragments
+                        // note if filesz is zero, we want zero init which is handled because the
+                        // statement above creates an empty page fragment list
+                        // check overlap with any existing fragments
+                        for (const auto &fragment : fragments) {
+                            if ((off < fragment.page_offset + fragment.bytes) !=
+                                ((off + len) <= fragment.page_offset)) {
+                                fail(ERROR_FORMAT, "In memory segments overlap");
+                            }
+                        }
+                        fragments.push_back(
+                                page_fragment{file_offset,off,len});
+                        addr += len;
+                        file_offset += len;
+                        remaining -= len;
+                    }
+                }
+                if (entry.memsz > entry.filez) {
+                    // we have some uninitialized data too
+                    rc = check_address_range(valid_ranges, entry.paddr + entry.filez, entry.vaddr + entry.filez, entry.memsz - entry.filez, true,
+                                             ar);
+                    if (rc) return rc;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+int realize_page(FILE *in, const std::vector<page_fragment> &fragments, uint8_t *buf, uint buf_len) {
+    assert(buf_len >= PAGE_SIZE);
+    for(auto& frag : fragments) {
+        assert(frag.page_offset >= 0 && frag.page_offset < PAGE_SIZE && frag.page_offset + frag.bytes <= PAGE_SIZE);
+        if (fseek(in, frag.file_offset, SEEK_SET)) {
+            return fail_read_error();
+        }
+        if (1 != fread(buf + frag.page_offset, frag.bytes, 1, in)) {
+            return fail_read_error();
+        }
+    }
+    return 0;
+}
+
+static bool is_address_valid(const address_ranges& valid_ranges, uint32_t addr) {
+    for(const auto& range : valid_ranges) {
+        if (range.from <= addr && range.to > addr) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static bool is_address_initialized(const address_ranges& valid_ranges, uint32_t addr) {
+    for(const auto& range : valid_ranges) {
+        if (range.from <= addr && range.to > addr) {
+            return address_range::type::CONTENTS == range.type;
+        }
+    }
+    return false;
+}
+
+static bool is_address_mapped(const std::map<uint32_t, std::vector<page_fragment>>& pages, uint32_t addr) {
+    uint32_t page = addr & ~(PAGE_SIZE - 1);
+    if (!pages.count(page)) return false;
+    // todo check actual address within page
+    return true;
+}
+
+int elf2uf2(FILE *in, FILE *out) {
+    elf32_header eh;
+    std::map<uint32_t, std::vector<page_fragment>> pages;
+    int rc = read_and_check_elf32_header(in, eh);
+    bool ram_style = false;
+    address_ranges valid_ranges = {};
+    if (!rc) {
+        ram_style = is_address_initialized(rp2040_address_ranges_ram, eh.entry);
+        if (verbose) {
+            if (ram_style) {
+                printf("Detected RAM binary\n");
+            } else {
+                printf("Detected FLASH binary\n");
+            }
+        }
+        valid_ranges = ram_style ? rp2040_address_ranges_ram : rp2040_address_ranges_flash;
+        rc = read_and_check_elf32_ph_entries(in, eh, valid_ranges, pages);
+    }
+    if (rc) return rc;
+    if (pages.empty()) {
+        return fail(ERROR_INCOMPATIBLE, "The input file has no memory pages");
+    }
+    uint page_num = 0;
+    if (ram_style) {
+        uint32_t expected_ep_main_ram = UINT32_MAX;
+        uint32_t expected_ep_xip_sram = UINT32_MAX;
+        for(auto& page_entry : pages) {
+            if ( ((page_entry.first >= MAIN_RAM_START) && (page_entry.first < MAIN_RAM_END)) && (page_entry.first < expected_ep_main_ram) ) {
+                expected_ep_main_ram = page_entry.first | 0x1;
+            } else if ( ((page_entry.first >= XIP_SRAM_START) && (page_entry.first < XIP_SRAM_END)) && (page_entry.first < expected_ep_xip_sram) ) { 
+                expected_ep_xip_sram = page_entry.first | 0x1;
+            }
+        }
+        uint32_t expected_ep = (UINT32_MAX != expected_ep_main_ram) ? expected_ep_main_ram : expected_ep_xip_sram;
+        if (eh.entry == expected_ep_xip_sram) {
+            return fail(ERROR_INCOMPATIBLE, "B0/B1 Boot ROM does not support direct entry into XIP_SRAM\n");
+        } else if (eh.entry != expected_ep) {
+            return fail(ERROR_INCOMPATIBLE, "A RAM binary should have an entry point at the beginning: %08x (not %08x)\n", expected_ep, eh.entry);
+        }
+        static_assert(0 == (MAIN_RAM_START & (PAGE_SIZE - 1)), "");
+        // currently don't require this as entry point is now at the start, we don't know where reset vector is
+#if 0
+        uint8_t buf[PAGE_SIZE];
+        rc = realize_page(in, pages[MAIN_RAM_START], buf, sizeof(buf));
+        if (rc) return rc;
+        uint32_t sp = ((uint32_t *)buf)[0];
+        uint32_t ip = ((uint32_t *)buf)[1];
+        if (!is_address_mapped(pages, ip)) {
+            return fail(ERROR_INCOMPATIBLE, "Vector table at %08x is invalid: reset vector %08x is not in mapped memory",
+                MAIN_RAM_START, ip);
+        }
+        if (!is_address_valid(valid_ranges, sp - 4)) {
+            return fail(ERROR_INCOMPATIBLE, "Vector table at %08x is invalid: stack pointer %08x is not in RAM",
+                        MAIN_RAM_START, sp);
+        }
+#endif
+    }
+    uf2_block block;
+    block.magic_start0 = UF2_MAGIC_START0;
+    block.magic_start1 = UF2_MAGIC_START1;
+    block.flags = UF2_FLAG_FAMILY_ID_PRESENT;
+    block.payload_size = PAGE_SIZE;
+    block.num_blocks = (uint32_t)pages.size();
+    block.file_size = RP2040_FAMILY_ID;
+    block.magic_end = UF2_MAGIC_END;
+    for(auto& page_entry : pages) {
+        block.target_addr = page_entry.first;
+        block.block_no = page_num++;
+        if (verbose) {
+            printf("Page %d / %d %08x\n", block.block_no, block.num_blocks, block.target_addr);
+        }
+        memset(block.data, 0, sizeof(block.data));
+        rc = realize_page(in, page_entry.second, block.data, sizeof(block.data));
+        if (rc) return rc;
+        if (1 != fwrite(&block, sizeof(uf2_block), 1, out)) {
+            return fail_write_error();
+        }
+    }
+    return 0;
+}
+
+int main(int argc, char **argv) {
+    int arg = 1;
+    if (arg < argc && !strcmp(argv[arg], "-v")) {
+        verbose = true;
+        arg++;
+    }
+    if (argc < arg + 2) {
+        return usage();
+    }
+    const char *in_filename = argv[arg++];
+    FILE *in = fopen(in_filename, "rb");
+    if (!in) {
+        fprintf(stderr, "Can't open input file '%s'\n", in_filename);
+        return ERROR_ARGS;
+    }
+    const char *out_filename = argv[arg++];
+    FILE *out = fopen(out_filename, "wb");
+    if (!out) {
+        fprintf(stderr, "Can't open output file '%s'\n", out_filename);
+        return ERROR_ARGS;
+    }
+
+    int rc = elf2uf2(in, out);
+    fclose(in);
+    fclose(out);
+    if (rc) {
+        remove(out_filename);
+        if (error_msg[0]) {
+            fprintf(stderr, "ERROR: %s\n", error_msg);
+        }
+    }
+    return rc;
+}
