Boot: integrate MCUBoot with TF-M to act as a BL2 bootloader

Modifications in MCUBoot to be aligned with BL2 requirements in TF-M:
 -- OS dependency was removed, no need to copy any OS repo to build it
 -- CMSIS serial driver is used
 -- flash driver interface is aligned with original version
 -- S and NS images are handeled as a single binary blob
 -- automatic image concatenation and signing at build time
 -- authentication based on SHA256 and RSA-2048 digital signature
 -- mbedTLS library is used for cryptographic operation
 -- static analyser warnings fixed in some files

Change-Id: I54891762eac8d0df634e954ff19a9505b16f3028
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/.gitignore b/.gitignore
index d309db4..baecae8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,9 +6,10 @@
 .settings/
 
 # Garbage files
-build/
+build*/
 objects/
 bin/
 test/*.a
 secure_fw/services/secure_storage/*.o
 secure_fw/services/secure_storage/*.a
+*.orig
diff --git a/BuildMbedtls.cmake b/BuildMbedtls.cmake
new file mode 100644
index 0000000..8df2b78
--- /dev/null
+++ b/BuildMbedtls.cmake
@@ -0,0 +1,84 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2017, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#When included, this file will add a target to build the mbedtls libraries with
+#the same compilation setting as used by the file including this one.
+cmake_minimum_required(VERSION 3.7)
+
+#Define where mbedtls intermediate output files are stored.
+set (MBEDTLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/mbedtls")
+
+#Check input variables
+if(NOT DEFINED MBEDTLS_BUILD_TYPE)
+	message(FATAL_ERROR "Please set MBEDTLS_BUILD_TYPE to 'Debug' or 'Release' before including this file.")
+endif()
+
+if(NOT DEFINED MBEDTLS_SOURCE_DIR)
+	message(FATAL_ERROR "Please set MBEDTLS_SOURCE_DIR before including this file.")
+endif()
+
+if(NOT DEFINED MBEDTLS_INSTALL_DIR)
+	message(FATAL_ERROR "Please set MBEDTLS_INSTALL_DIR before including this file.")
+endif()
+
+if(NOT DEFINED MBEDTLS_C_FLAGS)
+	message(FATAL_ERROR "Please set MBEDTLS_C_FLAGS before including this file.")
+endif()
+
+if(NOT DEFINED MBEDTLS_TARGET_NAME)
+	message(FATAL_ERROR "Please set MBEDTLS_TARGET_NAME before including this file.")
+endif()
+
+string(APPEND MBEDTLS_C_FLAGS ${CMAKE_C_FLAGS})
+
+if (TARGET ${MBEDTLS_TARGET_NAME})
+	message(FATAL_ERROR "A target with name ${MBEDTLS_TARGET_NAME} is already\
+defined. Please set MBEDTLS_TARGET_NAME to a unique value.")
+endif()
+
+#Build mbedtls as external project.
+#This ensures mbedtls is built with exactly defined settings.
+#mbedtls will be used from is't install location
+include(ExternalProject)
+# Add mbed TLS files to the build.
+set(_static_lib_command ${CMAKE_C_CREATE_STATIC_LIBRARY})
+externalproject_add(${MBEDTLS_TARGET_NAME}
+	SOURCE_DIR ${MBEDTLS_SOURCE_DIR}
+	#Set mbedtls features
+	CMAKE_ARGS -DENABLE_TESTING=OFF -DENABLE_PROGRAMS=OFF
+	#Enforce our build system's settings.
+	CMAKE_ARGS -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
+	#Inherit the build setting of this project
+	CMAKE_ARGS -DCMAKE_BUILD_TYPE=${MBEDTLS_BUILD_TYPE}
+	#C compiler settings
+	CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER:string=${CMAKE_C_COMPILER}
+	CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER_ID:string=${CMAKE_C_COMPILER_ID}
+	CMAKE_CACHE_ARGS -DCMAKE_C_FLAGS:string=${MBEDTLS_C_FLAGS}
+	CMAKE_CACHE_ARGS -DCMAKE_C_FLAGS_DEBUG:string=${CMAKE_C_FLAGS_DEBUG}
+	CMAKE_CACHE_ARGS -DCMAKE_C_FLAGS_RELEASE:string=${CMAKE_C_FLAGS_RELEASE}
+	CMAKE_CACHE_ARGS -DCMAKE_C_OUTPUT_EXTENSION:string=.o
+	CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER_WORKS:bool=true
+	#Archiver settings
+	CMAKE_CACHE_ARGS -DCMAKE_AR:string=${CMAKE_AR}
+	CMAKE_CACHE_ARGS -DCMAKE_C_CREATE_STATIC_LIBRARY:internal=${_static_lib_command}
+	CMAKE_CACHE_ARGS -DCMAKE_C_LINK_EXECUTABLE:string=${CMAKE_C_LINK_EXECUTABLE}
+	CMAKE_CACHE_ARGS -DCMAKE_STATIC_LIBRARY_PREFIX_C:string=${CMAKE_STATIC_LIBRARY_PREFIX_C}
+	CMAKE_CACHE_ARGS -DCMAKE_STATIC_LIBRARY_PREFIX_CXX:string=${CMAKE_STATIC_LIBRARY_PREFIX_CXX}
+	#Install location
+	CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:string=${MBEDTLS_INSTALL_DIR}
+	#Place for intermediate build files
+	BINARY_DIR ${MBEDTLS_BINARY_DIR})
+
+#Add an install target to force installation after each mbedtls build. Without
+#this target installation happens only when a clean mbedtls build is executed.
+add_custom_target(${MBEDTLS_TARGET_NAME}_install
+	 COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/mbedtls -- install
+	 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mbedtls
+	 COMMENT "Installing mbedtls to ${MBEDTLS_INSTALL_DIR}"
+	 VERBATIM)
+#Make install rule depend on mbedtls library build
+add_dependencies(${MBEDTLS_TARGET_NAME}_install ${MBEDTLS_TARGET_NAME})
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 90d1d70..1b6d722 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,6 +11,7 @@
 include("Common/BuildSys")
 
 add_subdirectory(app)
+add_subdirectory(bl2/ext/mcuboot)
 
 #Define a top-level generic tfm project
 project(tfm LANGUAGES)
diff --git a/ConfigCoreTest.cmake b/ConfigCoreTest.cmake
index dc059a3..5ab23fb 100644
--- a/ConfigCoreTest.cmake
+++ b/ConfigCoreTest.cmake
@@ -20,7 +20,7 @@
 #definitions) based on these.
 set (REGRESSION False)
 set (CORE_TEST True)
-set (MCUBOOT False)
+set (BL2 True)
 
 ##Shared compiler and linker settings.
 function(config_setting_shared_flags tgt)
@@ -86,8 +86,8 @@
 	add_definitions(-DCORE_TEST_SERVICES)
 endif()
 
-if (MCUBOOT)
-	add_definitions(-DMCUBOOT)
+if (BL2)
+	add_definitions(-DBL2)
 endif()
 
 ##Secure side
@@ -111,3 +111,7 @@
 ##Tests
 config_setting_shared_flags(tfm_secure_tests)
 config_setting_shared_flags(tfm_non_secure_tests)
+
+##BL2
+config_setting_shared_flags(mcuboot)
+set(MBEDTLS_C_FLAGS_BL2 "-D__ARM_FEATURE_CMSE=3 -D__thumb2__ -fshort-enums -mfpu=none -fshort-wchar -funsigned-char -mcmse  -DMBEDTLS_CONFIG_FILE=\\\\\\\"config-boot.h\\\\\\\" -I${CMAKE_CURRENT_LIST_DIR}/bl2/ext/mcuboot/include")
diff --git a/ConfigDefault.cmake b/ConfigDefault.cmake
index 2f210f4..d9eea39 100644
--- a/ConfigDefault.cmake
+++ b/ConfigDefault.cmake
@@ -21,7 +21,7 @@
 #definitions) based on these.
 set (REGRESSION False)
 set (CORE_TEST False)
-set (MCUBOOT False)
+set (BL2 True)
 
 ##Shared compiler and linker settings.
 function(config_setting_shared_flags tgt)
@@ -86,8 +86,8 @@
 	add_definitions(-DCORE_TEST_SERVICES)
 endif()
 
-if (MCUBOOT)
-	add_definitions(-DMCUBOOT)
+if (BL2)
+	add_definitions(-DBL2)
 endif()
 
 ##Secure side
@@ -111,3 +111,7 @@
 ##Tests
 config_setting_shared_flags(tfm_secure_tests)
 config_setting_shared_flags(tfm_non_secure_tests)
+
+##BL2
+config_setting_shared_flags(mcuboot)
+set(MBEDTLS_C_FLAGS_BL2 "-D__ARM_FEATURE_CMSE=3 -D__thumb2__ -fshort-enums -mfpu=none -fshort-wchar -funsigned-char -mcmse  -DMBEDTLS_CONFIG_FILE=\\\\\\\"config-boot.h\\\\\\\" -I${CMAKE_CURRENT_LIST_DIR}/bl2/ext/mcuboot/include")
diff --git a/ConfigRegression.cmake b/ConfigRegression.cmake
index 09958d1..a563d93 100644
--- a/ConfigRegression.cmake
+++ b/ConfigRegression.cmake
@@ -26,7 +26,7 @@
 #definitions) based on these.
 set (REGRESSION True)
 set (CORE_TEST False)
-set (MCUBOOT False)
+set (BL2 True)
 
 ##Shared compiler and linker settings.
 function(config_setting_shared_flags tgt)
@@ -91,8 +91,8 @@
 	add_definitions(-DCORE_TEST_SERVICES)
 endif()
 
-if (MCUBOOT)
-	add_definitions(-DMCUBOOT)
+if (BL2)
+	add_definitions(-DBL2)
 endif()
 
 ##Secure side
@@ -116,3 +116,7 @@
 ##Tests
 config_setting_shared_flags(tfm_secure_tests)
 config_setting_shared_flags(tfm_non_secure_tests)
+
+##BL2
+config_setting_shared_flags(mcuboot)
+set(MBEDTLS_C_FLAGS_BL2 "-D__ARM_FEATURE_CMSE=3 -D__thumb2__ -fshort-enums -mfpu=none -fshort-wchar -funsigned-char -mcmse  -DMBEDTLS_CONFIG_FILE=\\\\\\\"config-boot.h\\\\\\\" -I${CMAKE_CURRENT_LIST_DIR}/bl2/ext/mcuboot/include")
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 373d596..58912a5 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -52,6 +52,7 @@
 set(MPS2_SSE200_BUILD_UART_STDOUT Off)
 set(MPS2_SSE200_BUILD_MPS2_BOARD_LEDS On)
 set(MPS2_SSE200_BUILD_MPS2_BOARD_TIME On)
+set(MPS2_SSE200_BUILD_MPS2_BOARD_FLASH Off)
 include(${TFM_ROOT_DIR}/platform/ext/Mps2SSE200.cmake)
 
 #Set include directories.
@@ -69,8 +70,43 @@
 #Add the RTX library
 target_link_libraries(${PROJECT_NAME} "${CMSIS_5_DIR}/CMSIS/RTOS2/RTX/Library/ARM/RTX_V8MMN.lib")
 #Set macro definitions
-target_compile_definitions(${PROJECT_NAME} PRIVATE __thumb2__ __DOMAIN_NS=1 __ARM_FEATURE_CMSE=3 LOG_MSG_HANDLER_MODE_PRINTF_ENABLED
-    )
+target_compile_definitions(${PROJECT_NAME} PRIVATE __thumb2__ __DOMAIN_NS=1 __ARM_FEATURE_CMSE=3 LOG_MSG_HANDLER_MODE_PRINTF_ENABLED)
+
+#Generate binary file from axf
+compiler_generate_binary_output(${PROJECT_NAME})
+
+#Generate MCUBoot compatiable payload
+if (DEFINED BL2)
+	#Include Python3.x interpreter
+	set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
+	find_package(PythonInterp)
+	if (NOT PYTHONINTERP_FOUND)
+		message(FATAL_ERROR "Missing Python3.x interpreter, install it!")
+	endif()
+
+	set(MCUBOOT_DIR ${TFM_ROOT_DIR}/bl2/ext/mcuboot)
+
+	add_custom_command(TARGET ${PROJECT_NAME}
+						POST_BUILD
+
+						#Create concatenated binary image from tfm_ns.bin and tfm_s.bin
+						COMMAND ${PYTHON_EXECUTABLE} ${MCUBOOT_DIR}/scripts/assemble.py
+						ARGS -s $<TARGET_FILE_DIR:tfm_s>/tfm_s.bin
+							 -n $<TARGET_FILE_DIR:tfm_ns>/tfm_ns.bin
+							 -o ${CMAKE_BINARY_DIR}/app/tfm_full.bin
+
+						#Sign concatenated binary image with default public key in mcuboot folder
+						COMMAND ${PYTHON_EXECUTABLE} ${MCUBOOT_DIR}/scripts/imgtool.py
+						ARGS sign
+							 -k ${MCUBOOT_DIR}/root-rsa-2048.pem
+							 --align 1
+							 -v 1.0
+							 -H 0x200
+							 --pad 0x100000
+							 ${CMAKE_BINARY_DIR}/app/tfm_full.bin
+							 ${CMAKE_BINARY_DIR}/app/tfm_sign.bin
+				)
+endif()
 
 if (NOT DEFINED CORE_TEST)
 	message(FATAL_ERROR "Incomplete build configuration: CORE_TEST is undefined. ")
@@ -84,11 +120,11 @@
 	set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DCORE_TEST_SERVICES\"")
 endif()
 
-#Set MCUBOOT specific settings.
-if (NOT DEFINED MCUBOOT)
-	message(FATAL_ERROR "Incomplete build configuration: MCUBOOT is undefined. ")
-elseif (MCUBOOT)
-    set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DMCUBOOT\"")
+#Set BL2 specific settings.
+if (NOT DEFINED BL2)
+	message(FATAL_ERROR "Incomplete build configuration: BL2 is undefined. ")
+elseif (BL2)
+	set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DBL2\"")
 endif()
 
 
diff --git a/bl2/ext/mcuboot/CMakeLists.txt b/bl2/ext/mcuboot/CMakeLists.txt
new file mode 100644
index 0000000..b98a66e
--- /dev/null
+++ b/bl2/ext/mcuboot/CMakeLists.txt
@@ -0,0 +1,122 @@
+#------------------------------------------------------------------------------
+# Copyright (c) 2017, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#------------------------------------------------------------------------------
+
+cmake_minimum_required(VERSION 3.7)
+
+#Tell cmake where our modules can be found
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../../../cmake)
+
+#Include common stuff to control cmake.
+include("Common/BuildSys")
+
+#Start an embedded project.
+embedded_project_start(CONFIG "${CMAKE_CURRENT_LIST_DIR}/../../../ConfigDefault.cmake")
+project(mcuboot LANGUAGES ASM C)
+embedded_project_fixup()
+
+#Check input variables
+if (NOT DEFINED BL2)
+   message(FATAL ERROR "Incomplete build configuration: BL2 is undefined.")
+elseif(NOT BL2)
+    #If mcuboot is not need to be built then stop further processing.
+    return()
+endif()
+
+if (NOT DEFINED MBEDTLS_DEBUG)
+	message(FATAL_ERROR "Incomplete build configuration: MBEDTLS_DEBUG is undefined.")
+endif()
+
+if (NOT DEFINED MBEDTLS_C_FLAGS_BL2)
+	message(FATAL_ERROR "Incomplete build configuration: MBEDTLS_C_FLAGS_BL2 is undefined.")
+endif()
+
+#Set variables to appropriate path
+set(MCUBOOT_DIR ${CMAKE_CURRENT_LIST_DIR})
+get_filename_component(TFM_ROOT_DIR "${MCUBOOT_DIR}/../../.." ABSOLUTE)
+
+set(MPS2_SSE200_BUILD_CMSIS_CORE On)
+set(MPS2_SSE200_BUILD_RETARGET On)
+set(MPS2_SSE200_BUILD_NATIVE_DRIVERS On)
+set(MPS2_SSE200_BUILD_STARTUP On)
+set(MPS2_SSE200_BUILD_TARGET_CFG Off)
+set(MPS2_SSE200_BUILD_TARGET_HARDWARE_KEYS Off)
+set(MPS2_SSE200_BUILD_CMSIS_DRIVERS On)
+set(MPS2_SSE200_BUILD_MPS2_TIME Off)
+set(MPS2_SSE200_BUILD_UART_STDOUT On)
+set(MPS2_SSE200_BUILD_MPS2_BOARD_LEDS Off)
+set(MPS2_SSE200_BUILD_MPS2_BOARD_TIME On)
+set(MPS2_SSE200_BUILD_MPS2_BOARD_FLASH On)
+include(${TFM_ROOT_DIR}/platform/ext/Mps2SSE200.cmake)
+
+#Append all our source files to global lists.
+list(APPEND ALL_SRC_C "${MCUBOOT_DIR}/bl2_main.c"
+		"${MCUBOOT_DIR}/flash_map.c"
+		"${MCUBOOT_DIR}/hal_flash.c"
+		"${MCUBOOT_DIR}/os.c"
+		"${MCUBOOT_DIR}/keys.c"
+		"${MCUBOOT_DIR}/bootutil/src/loader.c"
+		"${MCUBOOT_DIR}/bootutil/src/bootutil_misc.c"
+		"${MCUBOOT_DIR}/bootutil/src/image_validate.c"
+		"${MCUBOOT_DIR}/bootutil/src/image_rsa.c"
+		"${MCUBOOT_DIR}/bootutil/src/caps.c"
+	)
+
+#Define location of mbedtls source, build, and installation directory.
+get_filename_component(MBEDTLS_SOURCE_DIR "${TFM_ROOT_DIR}/../mbedtls" ABSOLUTE)
+if(NOT EXISTS ${MBEDTLS_SOURCE_DIR})
+	message(FATAL_ERROR "Missing mbedtls. Please clone the mbedtls repo to directory \"${MBEDTLS_SOURCE_DIR}\".")
+endif()
+set (MBEDTLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/mbedtls")
+set (MBEDTLS_INSTALL_DIR ${MBEDTLS_BINARY_DIR}/mbedtls_install)
+
+#Set build type for mbedtls libraries
+if (MBEDTLS_DEBUG)
+	set(MBEDTLS_BUILD_TYPE "Debug")
+else()
+	set(MBEDTLS_BUILD_TYPE "Release")
+endif()
+
+#Build mbedtls as external project.
+#This ensures mbedtls is built with exactly defined settings.
+#mbedtls will be used from is't install location
+set(MBEDTLS_C_FLAGS ${MBEDTLS_C_FLAGS_BL2})
+set(MBEDTLS_TARGET_NAME "mbedtls_mcuboot_lib")
+include(${TFM_ROOT_DIR}/BuildMbedtls.cmake)
+
+#Setting include directories
+embedded_include_directories(PATH ${TFM_ROOT_DIR} ABSOLUTE APPEND)
+embedded_include_directories(PATH ${TFM_ROOT_DIR}/bl2/ext/mcuboot/include ABSOLUTE APPEND)
+embedded_include_directories(PATH ${TFM_ROOT_DIR}/bl2/ext/mcuboot/bootutil/include/ ABSOLUTE APPEND)
+embedded_include_directories(PATH ${MBEDTLS_INSTALL_DIR}/include ABSOLUTE APPEND)
+
+#Define linker file
+embedded_set_target_linker_file(TARGET mcuboot PATH "${TFM_ROOT_DIR}/platform/ext/target/sse_200_mps2/sse_200/armclang/sse_200_bl2.sct")
+
+add_executable(${PROJECT_NAME} ${MCUBOOT_SRC} ${ALL_SRC_ASM_BL2} ${ALL_SRC_C} ${ALL_SRC_CXX})
+
+#Add BL2 define to linker to resolve symbols in region_defs.h
+set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DBL2\"")
+
+#Link mbedcrypto library to project
+target_link_libraries(${PROJECT_NAME} "${MBEDTLS_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX_C}mbedcrypto${CMAKE_STATIC_LIBRARY_SUFFIX_C}")
+add_dependencies(${PROJECT_NAME} ${MBEDTLS_TARGET_NAME}_install)
+
+
+#Generate binary file from axf
+compiler_generate_binary_output(${PROJECT_NAME})
+
+#Set macro definitions for the project.
+target_compile_definitions(${PROJECT_NAME} PRIVATE
+							MCUBOOT_SIGN_RSA
+							MCUBOOT_VALIDATE_SLOT0
+							MCUBOOT_USE_FLASH_AREA_GET_SECTORS
+							MBEDTLS_CONFIG_FILE="config-boot.h"
+							MCUBOOT_TARGET_CONFIG="flash_layout.h"
+						)
+
+#Finally let cmake system apply changes after the whole project is defined.
+embedded_project_end(${PROJECT_NAME})
diff --git a/bl2/ext/mcuboot/main.c b/bl2/ext/mcuboot/bl2_main.c
similarity index 64%
rename from bl2/ext/mcuboot/main.c
rename to bl2/ext/mcuboot/bl2_main.c
index cdd4139..565c547 100644
--- a/bl2/ext/mcuboot/main.c
+++ b/bl2/ext/mcuboot/bl2_main.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012-2014 Wind River Systems, Inc.
+ * Copyright (c) 2017, Arm Limited.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,12 +16,11 @@
  */
 
 #include <assert.h>
-#include <zephyr.h>
-#include <flash.h>
-#include <asm_inline.h>
-#include <drivers/system_timer.h>
-
+#include "bl2_util.h"
 #include "target.h"
+#include "cmsis.h"
+#include "uart_stdout.h"
+
 
 #define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_INFO
 #include "bootutil/bootutil_log.h"
@@ -28,13 +28,17 @@
 #include "bootutil/bootutil.h"
 #include "flash_map/flash_map.h"
 
-struct device *boot_flash_device;
+/* Avoids the semihosting issue */
+#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+__asm("  .global __ARM_use_no_argv\n");
+#endif
+
+/* Keep these variables to be compatible with flash API */
+struct device tmp;
+struct device *boot_flash_device = &tmp;
 
 void os_heap_init(void);
 
-extern void zephyr_flash_area_warn_on_open(void);
-
-#if defined(CONFIG_ARM)
 struct arm_vector_table {
     uint32_t msp;
     uint32_t reset;
@@ -42,7 +46,12 @@
 
 static void do_boot(struct boot_rsp *rsp)
 {
-    struct arm_vector_table *vt;
+    /* Clang at O0, stores variables on the stack with SP relative addressing.
+     * When manually set the SP then the place of reset vector is lost.
+     * Static variables are stored in 'data' or 'bss' section, change of SP has
+     * no effect on them.
+     */
+    static struct arm_vector_table *vt;
     uintptr_t flash_base;
     int rc;
 
@@ -57,50 +66,25 @@
     vt = (struct arm_vector_table *)(flash_base +
                                      rsp->br_image_off +
                                      rsp->br_hdr->ih_hdr_size);
-    irq_lock();
-    sys_clock_disable();
-    _MspSet(vt->msp);
+    __disable_irq();
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
     ((void (*)(void))vt->reset)();
 }
-#else
-/* Default: Assume entry point is at the very beginning of the image. Simply
- * lock interrupts and jump there. This is the right thing to do for X86 and
- * possibly other platforms.
- */
-static void do_boot(struct boot_rsp *rsp)
-{
-    uintptr_t flash_base;
-    void *start;
-    int rc;
 
-    rc = flash_device_base(rsp->br_flash_dev_id, &flash_base);
-    assert(rc == 0);
-
-    start = (void *)(flash_base + rsp->br_image_off +
-                     rsp->br_hdr->ih_hdr_size);
-
-    /* Lock interrupts and dive into the entry point */
-    irq_lock();
-    ((void (*)(void))start)();
-}
-#endif
-
-void main(void)
+int main(void)
 {
     struct boot_rsp rsp;
     int rc;
 
+    uart_init(UART0_CHANNEL);
+
     BOOT_LOG_INF("Starting bootloader");
 
     os_heap_init();
 
-    boot_flash_device = device_get_binding(FLASH_DRIVER_NAME);
-    if (!boot_flash_device) {
-        BOOT_LOG_ERR("Flash device not found");
-        while (1)
-            ;
-    }
-
     rc = boot_go(&rsp);
     if (rc != 0) {
         BOOT_LOG_ERR("Unable to find bootable image");
@@ -110,7 +94,7 @@
 
     BOOT_LOG_INF("Bootloader chainload address offset: 0x%x",
                  rsp.br_image_off);
-    zephyr_flash_area_warn_on_open();
+    flash_area_warn_on_open();
     BOOT_LOG_INF("Jumping to the first image slot");
     do_boot(&rsp);
 
diff --git a/bl2/ext/mcuboot/bootutil/include/bootutil/bootutil_log.h b/bl2/ext/mcuboot/bootutil/include/bootutil/bootutil_log.h
index 643fc99..ba161d4 100644
--- a/bl2/ext/mcuboot/bootutil/include/bootutil/bootutil_log.h
+++ b/bl2/ext/mcuboot/bootutil/include/bootutil/bootutil_log.h
@@ -23,62 +23,17 @@
 extern "C" {
 #endif
 
-/*
- * When building for targets running Zephyr, delegate to its native
- * logging subsystem.
- *
- * In this case:
- *
- * - BOOT_LOG_LEVEL determines SYS_LOG_LEVEL,
- * - BOOT_LOG_ERR() and friends are SYS_LOG_ERR() etc.
- * - SYS_LOG_DOMAIN is unconditionally set to "MCUBOOT"
- */
-#ifdef __ZEPHYR__
-
-#define BOOT_LOG_LEVEL_OFF	SYS_LOG_LEVEL_OFF
-#define BOOT_LOG_LEVEL_ERROR	SYS_LOG_LEVEL_ERROR
-#define BOOT_LOG_LEVEL_WARNING	SYS_LOG_LEVEL_WARNING
-#define BOOT_LOG_LEVEL_INFO	SYS_LOG_LEVEL_INFO
-#define BOOT_LOG_LEVEL_DEBUG	SYS_LOG_LEVEL_DEBUG
-
-/* Treat BOOT_LOG_LEVEL equivalently to SYS_LOG_LEVEL. */
-#ifndef BOOT_LOG_LEVEL
-#define BOOT_LOG_LEVEL CONFIG_SYS_LOG_DEFAULT_LEVEL
-#elif (BOOT_LOG_LEVEL < CONFIG_SYS_LOG_OVERRIDE_LEVEL)
-#undef BOOT_LOG_LEVEL
-#define BOOT_LOG_LEVEL CONFIG_SYS_LOG_OVERRIDE_LEVEL
-#endif
-
-#define SYS_LOG_LEVEL BOOT_LOG_LEVEL
-
-#undef SYS_LOG_DOMAIN
-#define SYS_LOG_DOMAIN "MCUBOOT"
-
-#define BOOT_LOG_ERR(...) SYS_LOG_ERR(__VA_ARGS__)
-#define BOOT_LOG_WRN(...) SYS_LOG_WRN(__VA_ARGS__)
-#define BOOT_LOG_INF(...) SYS_LOG_INF(__VA_ARGS__)
-#define BOOT_LOG_DBG(...) SYS_LOG_DBG(__VA_ARGS__)
-
-#include <logging/sys_log.h>
-
-/*
- * When built on the simulator, just use printf().
- */
-#elif defined(__BOOTSIM__)	/* !defined(__ZEPHYR__) */
-
 #include <stdio.h>
 
-#define BOOT_LOG_LEVEL_OFF	0
-#define BOOT_LOG_LEVEL_ERROR	1
-#define BOOT_LOG_LEVEL_WARNING	2
-#define BOOT_LOG_LEVEL_INFO	3
-#define BOOT_LOG_LEVEL_DEBUG	4
+#define BOOT_LOG_LEVEL_OFF      0
+#define BOOT_LOG_LEVEL_ERROR    1
+#define BOOT_LOG_LEVEL_WARNING  2
+#define BOOT_LOG_LEVEL_INFO     3
+#define BOOT_LOG_LEVEL_DEBUG    4
 
 /*
  * The compiled log level determines the maximum level that can be
- * printed.  Messages at or below this level can be printed, provided
- * they are also enabled through the Rust logging system, such as by
- * setting RUST_LOG to bootsim::api=info.
+ * printed. Messages at or below this level can be printed.
  */
 #ifndef BOOT_LOG_LEVEL
 #define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_INFO
@@ -87,67 +42,33 @@
 int sim_log_enabled(int level);
 
 #if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_ERROR
-#define BOOT_LOG_ERR(_fmt, ...)                                         \
-    do {                                                                \
-        if (sim_log_enabled(BOOT_LOG_LEVEL_ERROR)) {                    \
-            fprintf(stderr, "[ERR] " _fmt "\n", ##__VA_ARGS__);         \
-        }                                                               \
-    } while (0)
+#define BOOT_LOG_ERR(_fmt, ...)                  \
+    printf("[ERR] " _fmt "\r\n", ##__VA_ARGS__)
 #else
 #define BOOT_LOG_ERR(...) IGNORE(__VA_ARGS__)
 #endif
 
 #if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_WARNING
-#define BOOT_LOG_WRN(_fmt, ...)                                         \
-    do {                                                                \
-        if (sim_log_enabled(BOOT_LOG_LEVEL_WARNING)) {                  \
-            fprintf(stderr, "[WRN] " _fmt "\n", ##__VA_ARGS__);         \
-        }                                                               \
-    } while (0)
+#define BOOT_LOG_WRN(_fmt, ...)                  \
+    printf("[WRN] " _fmt "\r\n", ##__VA_ARGS__)
 #else
 #define BOOT_LOG_WRN(...) IGNORE(__VA_ARGS__)
 #endif
 
 #if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_INFO
-#define BOOT_LOG_INF(_fmt, ...)                                         \
-    do {                                                                \
-        if (sim_log_enabled(BOOT_LOG_LEVEL_INFO)) {                     \
-            fprintf(stderr, "[INF] " _fmt "\n", ##__VA_ARGS__);         \
-        }                                                               \
-    } while (0)
+#define BOOT_LOG_INF(_fmt, ...)                  \
+    printf("[INF] " _fmt "\r\n", ##__VA_ARGS__)
 #else
 #define BOOT_LOG_INF(...) IGNORE(__VA_ARGS__)
 #endif
 
 #if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_DEBUG
-#define BOOT_LOG_DBG(_fmt, ...)                                         \
-    do {                                                                \
-        if (sim_log_enabled(BOOT_LOG_LEVEL_DEBUG)) {                    \
-            fprintf(stderr, "[DBG] " _fmt "\n", ##__VA_ARGS__);         \
-        }                                                               \
-    } while (0)
+#define BOOT_LOG_DBG(_fmt, ...)                  \
+    printf("[DBG] " _fmt "\r\n", ##__VA_ARGS__)
 #else
 #define BOOT_LOG_DBG(...) IGNORE(__VA_ARGS__)
 #endif
 
-/*
- * In other environments, logging calls are no-ops.
- */
-#else  /* !defined(__BOOTSIM__) */
-
-#define BOOT_LOG_LEVEL_OFF	0
-#define BOOT_LOG_LEVEL_ERROR	1
-#define BOOT_LOG_LEVEL_WARNING	2
-#define BOOT_LOG_LEVEL_INFO	3
-#define BOOT_LOG_LEVEL_DEBUG	4
-
-#define BOOT_LOG_ERR(...) IGNORE(__VA_ARGS__)
-#define BOOT_LOG_WRN(...) IGNORE(__VA_ARGS__)
-#define BOOT_LOG_INF(...) IGNORE(__VA_ARGS__)
-#define BOOT_LOG_DBG(...) IGNORE(__VA_ARGS__)
-
-#endif
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/bl2/ext/mcuboot/bootutil/include/bootutil/caps.h b/bl2/ext/mcuboot/bootutil/include/bootutil/caps.h
index a0c324a..6604e45 100644
--- a/bl2/ext/mcuboot/bootutil/include/bootutil/caps.h
+++ b/bl2/ext/mcuboot/bootutil/include/bootutil/caps.h
@@ -33,8 +33,6 @@
 uint32_t bootutil_get_caps(void);
 
 #define BOOTUTIL_CAP_RSA2048            (1<<0)
-#define BOOTUTIL_CAP_ECDSA_P224         (1<<1)
-#define BOOTUTIL_CAP_ECDSA_P256         (1<<2)
 #define BOOTUTIL_CAP_SWAP_UPGRADE       (1<<3)
 #define BOOTUTIL_CAP_OVERWRITE_UPGRADE  (1<<4)
 
diff --git a/bl2/ext/mcuboot/bootutil/include/bootutil/ignore.h b/bl2/ext/mcuboot/bootutil/include/bootutil/ignore.h
index 46282a0..4cc5430 100644
--- a/bl2/ext/mcuboot/bootutil/include/bootutil/ignore.h
+++ b/bl2/ext/mcuboot/bootutil/include/bootutil/ignore.h
@@ -30,25 +30,25 @@
  */
 
 #define IGN_1(X) ((void)(X))
-#define IGN_2(X, ...) ((void)(X));IGN_1(__VA_ARGS__)
-#define IGN_3(X, ...) ((void)(X));IGN_2(__VA_ARGS__)
-#define IGN_4(X, ...) ((void)(X));IGN_3(__VA_ARGS__)
-#define IGN_5(X, ...) ((void)(X));IGN_4(__VA_ARGS__)
-#define IGN_6(X, ...) ((void)(X));IGN_5(__VA_ARGS__)
-#define IGN_7(X, ...) ((void)(X));IGN_6(__VA_ARGS__)
-#define IGN_8(X, ...) ((void)(X));IGN_7(__VA_ARGS__)
-#define IGN_9(X, ...) ((void)(X));IGN_8(__VA_ARGS__)
-#define IGN_10(X, ...) ((void)(X));IGN_9(__VA_ARGS__)
-#define IGN_11(X, ...) ((void)(X));IGN_10(__VA_ARGS__)
-#define IGN_12(X, ...) ((void)(X));IGN_11(__VA_ARGS__)
-#define IGN_13(X, ...) ((void)(X));IGN_12(__VA_ARGS__)
-#define IGN_14(X, ...) ((void)(X));IGN_13(__VA_ARGS__)
-#define IGN_15(X, ...) ((void)(X));IGN_14(__VA_ARGS__)
-#define IGN_16(X, ...) ((void)(X));IGN_15(__VA_ARGS__)
-#define IGN_17(X, ...) ((void)(X));IGN_16(__VA_ARGS__)
-#define IGN_18(X, ...) ((void)(X));IGN_17(__VA_ARGS__)
-#define IGN_19(X, ...) ((void)(X));IGN_18(__VA_ARGS__)
-#define IGN_20(X, ...) ((void)(X));IGN_19(__VA_ARGS__)
+#define IGN_2(X, ...)  ((void)(X)); IGN_1(__VA_ARGS__)
+#define IGN_3(X, ...)  ((void)(X)); IGN_2(__VA_ARGS__)
+#define IGN_4(X, ...)  ((void)(X)); IGN_3(__VA_ARGS__)
+#define IGN_5(X, ...)  ((void)(X)); IGN_4(__VA_ARGS__)
+#define IGN_6(X, ...)  ((void)(X)); IGN_5(__VA_ARGS__)
+#define IGN_7(X, ...)  ((void)(X)); IGN_6(__VA_ARGS__)
+#define IGN_8(X, ...)  ((void)(X)); IGN_7(__VA_ARGS__)
+#define IGN_9(X, ...)  ((void)(X)); IGN_8(__VA_ARGS__)
+#define IGN_10(X, ...) ((void)(X)); IGN_9(__VA_ARGS__)
+#define IGN_11(X, ...) ((void)(X)); IGN_10(__VA_ARGS__)
+#define IGN_12(X, ...) ((void)(X)); IGN_11(__VA_ARGS__)
+#define IGN_13(X, ...) ((void)(X)); IGN_12(__VA_ARGS__)
+#define IGN_14(X, ...) ((void)(X)); IGN_13(__VA_ARGS__)
+#define IGN_15(X, ...) ((void)(X)); IGN_14(__VA_ARGS__)
+#define IGN_16(X, ...) ((void)(X)); IGN_15(__VA_ARGS__)
+#define IGN_17(X, ...) ((void)(X)); IGN_16(__VA_ARGS__)
+#define IGN_18(X, ...) ((void)(X)); IGN_17(__VA_ARGS__)
+#define IGN_19(X, ...) ((void)(X)); IGN_18(__VA_ARGS__)
+#define IGN_20(X, ...) ((void)(X)); IGN_19(__VA_ARGS__)
 
 #define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \
                   _13, _14, _15, _16, _17, _18, _19, _20, NAME, ...) NAME
diff --git a/bl2/ext/mcuboot/bootutil/include/bootutil/image.h b/bl2/ext/mcuboot/bootutil/include/bootutil/image.h
index 10e7be0..9a4535c 100644
--- a/bl2/ext/mcuboot/bootutil/include/bootutil/image.h
+++ b/bl2/ext/mcuboot/bootutil/include/bootutil/image.h
@@ -65,8 +65,6 @@
 #define IMAGE_TLV_KEYHASH           0x01   /* hash of the public key */
 #define IMAGE_TLV_SHA256            0x10   /* SHA256 of image hdr and body */
 #define IMAGE_TLV_RSA2048_PSS       0x20   /* RSA2048 of hash output */
-#define IMAGE_TLV_ECDSA224          0x21   /* ECDSA of hash output */
-#define IMAGE_TLV_ECDSA256          0x22   /* ECDSA of hash output */
 
 struct image_version {
     uint8_t iv_major;
diff --git a/bl2/ext/mcuboot/bootutil/include/bootutil/sha256.h b/bl2/ext/mcuboot/bootutil/include/bootutil/sha256.h
index cc52b07..8486ece 100644
--- a/bl2/ext/mcuboot/bootutil/include/bootutil/sha256.h
+++ b/bl2/ext/mcuboot/bootutil/include/bootutil/sha256.h
@@ -21,33 +21,13 @@
  * This module provides a thin abstraction over some of the crypto
  * primitives to make it easier to swap out the used crypto library.
  *
- * At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or
- * MCUBOOT_USE_TINYCRYPT.  It is a compile error there is not exactly
- * one of these defined.
+ * At this point, only mbedTLS is supported.
  */
 
 #ifndef __BOOTUTIL_CRYPTO_H_
 #define __BOOTUTIL_CRYPTO_H_
 
-#ifdef MCUBOOT_MYNEWT
-#include "mcuboot_config/mcuboot_config.h"
-#endif
-
-#if defined(MCUBOOT_USE_MBED_TLS) && defined(MCUBOOT_USE_TINYCRYPT)
-    #error "Cannot define both MBED_TLS and TINYCRYPT"
-#endif
-
-#if !defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_TINYCRYPT)
-    #error "One of MBED_TLS or TINYCRYPT must be defined"
-#endif
-
-#ifdef MCUBOOT_USE_MBED_TLS
-    #include <mbedtls/sha256.h>
-#endif /* MCUBOOT_USE_MBED_TLS */
-
-#ifdef MCUBOOT_USE_TINYCRYPT
-    #include <tinycrypt/sha256.h>
-#endif /* MCUBOOT_USE_TINYCRYPT */
+#include <mbedtls/sha256.h>
 
 #include <stdint.h>
 
@@ -55,7 +35,6 @@
 extern "C" {
 #endif
 
-#ifdef MCUBOOT_USE_MBED_TLS
 typedef mbedtls_sha256_context bootutil_sha256_context;
 
 static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
@@ -76,28 +55,6 @@
 {
     mbedtls_sha256_finish(ctx, output);
 }
-#endif /* MCUBOOT_USE_MBED_TLS */
-
-#ifdef MCUBOOT_USE_TINYCRYPT
-typedef struct tc_sha256_state_struct bootutil_sha256_context;
-static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
-{
-    tc_sha256_init(ctx);
-}
-
-static inline void bootutil_sha256_update(bootutil_sha256_context *ctx,
-                                          const void *data,
-                                          uint32_t data_len)
-{
-    tc_sha256_update(ctx, data, data_len);
-}
-
-static inline void bootutil_sha256_finish(bootutil_sha256_context *ctx,
-                                          uint8_t *output)
-{
-    tc_sha256_final(output, ctx);
-}
-#endif /* MCUBOOT_USE_TINYCRYPT */
 
 #ifdef __cplusplus
 }
diff --git a/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c b/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
index bf4e9b8..494879c 100644
--- a/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
+++ b/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
@@ -22,11 +22,8 @@
 #include <inttypes.h>
 #include <stddef.h>
 
-#include "sysflash/sysflash.h"
-#include "hal/hal_bsp.h"
 #include "hal/hal_flash.h"
 #include "flash_map/flash_map.h"
-#include "os/os.h"
 #include "bootutil/image.h"
 #include "bootutil/bootutil.h"
 #include "bootutil_priv.h"
@@ -43,7 +40,7 @@
     0x8079b62c,
 };
 
-const uint32_t BOOT_MAGIC_SZ = sizeof boot_img_magic;
+const uint32_t BOOT_MAGIC_SZ = sizeof(boot_img_magic);
 const uint32_t BOOT_MAX_ALIGN = MAX_FLASH_ALIGN;
 
 struct boot_swap_table {
@@ -95,7 +92,7 @@
 };
 
 #define BOOT_SWAP_TABLES_COUNT \
-    (sizeof boot_swap_tables / sizeof boot_swap_tables[0])
+    (sizeof(boot_swap_tables) / sizeof(boot_swap_tables[0]))
 
 int
 boot_magic_code(const uint32_t *magic)
@@ -106,7 +103,7 @@
         return BOOT_MAGIC_GOOD;
     }
 
-    for (i = 0; i < BOOT_MAGIC_SZ / sizeof *magic; i++) {
+    for (i = 0; i < BOOT_MAGIC_SZ / sizeof(*magic); i++) {
         if (magic[i] != 0xffffffff) {
             return BOOT_MAGIC_BAD;
         }
@@ -217,14 +214,15 @@
 
     if (fap->fa_id != FLASH_AREA_IMAGE_SCRATCH) {
         off = boot_copy_done_off(fap);
-        rc = flash_area_read(fap, off, &state->copy_done, sizeof state->copy_done);
+        rc = flash_area_read(fap, off, &state->copy_done,
+                             sizeof(state->copy_done));
         if (rc != 0) {
             return BOOT_EFLASH;
         }
     }
 
     off = boot_image_ok_off(fap);
-    rc = flash_area_read(fap, off, &state->image_ok, sizeof state->image_ok);
+    rc = flash_area_read(fap, off, &state->image_ok, sizeof(state->image_ok));
     if (rc != 0) {
         return BOOT_EFLASH;
     }
@@ -310,7 +308,7 @@
     }
 
     off = boot_swap_size_off(fap);
-    rc = flash_area_read(fap, off, swap_size, sizeof *swap_size);
+    rc = flash_area_read(fap, off, swap_size, sizeof(*swap_size));
     if (rc != 0) {
         rc = BOOT_EFLASH;
     }
@@ -392,11 +390,11 @@
     off = boot_swap_size_off(fap);
     align = hal_flash_align(fap->fa_device_id);
     assert(align <= BOOT_MAX_ALIGN);
-    if (align < sizeof swap_size) {
-        align = sizeof swap_size;
+    if (align < sizeof(swap_size)) {
+        align = sizeof(swap_size);
     }
     memset(buf, 0xFF, BOOT_MAX_ALIGN);
-    memcpy(buf, (uint8_t *)&swap_size, sizeof swap_size);
+    memcpy(buf, (uint8_t *)&swap_size, sizeof(swap_size));
 
     rc = flash_area_write(fap, off, buf, align);
     if (rc != 0) {
@@ -463,7 +461,7 @@
 int
 boot_set_pending(int permanent)
 {
-    const struct flash_area *fap;
+    const struct flash_area *fap = NULL;
     struct boot_swap_state state_slot1;
     int rc;
 
@@ -500,14 +498,15 @@
 }
 
 /**
- * Marks the image in slot 0 as confirmed.  The system will continue booting into the image in slot 0 until told to boot from a different slot.
+ * Marks the image in slot 0 as confirmed.  The system will continue booting
+ * into the image in slot 0 until told to boot from a different slot.
  *
- * @return                  0 on success; nonzero on failure.
+ * @return  0 on success; non-zero on failure.
  */
 int
 boot_set_confirmed(void)
 {
-    const struct flash_area *fap;
+    const struct flash_area *fap = NULL;
     struct boot_swap_state state_slot0;
     int rc;
 
diff --git a/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h b/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
index c1cf779..4753673 100644
--- a/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
+++ b/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
@@ -20,7 +20,6 @@
 #ifndef H_BOOTUTIL_PRIV_
 #define H_BOOTUTIL_PRIV_
 
-#include "sysflash/sysflash.h"
 #include "flash_map/flash_map.h"
 #include "bootutil/image.h"
 
diff --git a/bl2/ext/mcuboot/bootutil/src/caps.c b/bl2/ext/mcuboot/bootutil/src/caps.c
index 61d4f3f..e92e881 100644
--- a/bl2/ext/mcuboot/bootutil/src/caps.c
+++ b/bl2/ext/mcuboot/bootutil/src/caps.c
@@ -23,12 +23,6 @@
 #if defined(MCUBOOT_SIGN_RSA)
         res |= BOOTUTIL_CAP_RSA2048;
 #endif
-#if defined(MCUBOOT_SIGN_EC)
-        res |= BOOTUTIL_CAP_ECDSA_P224;
-#endif
-#if defined(MCUBOOT_SIGN_EC256)
-        res |= BOOTUTIL_CAP_ECDSA_P256;
-#endif
 #if defined(MCUBOOT_OVERWRITE_ONLY)
         res |= BOOTUTIL_CAP_OVERWRITE_UPGRADE;
 #else
diff --git a/bl2/ext/mcuboot/bootutil/src/image_rsa.c b/bl2/ext/mcuboot/bootutil/src/image_rsa.c
index 88ec784..4a472d5 100644
--- a/bl2/ext/mcuboot/bootutil/src/image_rsa.c
+++ b/bl2/ext/mcuboot/bootutil/src/image_rsa.c
@@ -19,10 +19,6 @@
 
 #include <string.h>
 
-#ifdef MCUBOOT_MYNEWT
-#include "mcuboot_config/mcuboot_config.h"
-#endif
-
 #ifdef MCUBOOT_SIGN_RSA
 #include "bootutil/sign_key.h"
 #include "bootutil/sha256.h"
@@ -68,11 +64,12 @@
 static int
 bootutil_parse_rsakey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
 {
-    int rc;
+    int rc, rc2;
     size_t len;
 
-    if ((rc = mbedtls_asn1_get_tag(p, end, &len,
-          MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+    rc = mbedtls_asn1_get_tag(p, end, &len,
+                            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+    if (rc != 0) {
         return -1;
     }
 
@@ -80,8 +77,9 @@
         return -2;
     }
 
-    if ((rc = mbedtls_asn1_get_mpi(p, end, &ctx->N)) != 0 ||
-      (rc = mbedtls_asn1_get_mpi(p, end, &ctx->E)) != 0) {
+    rc  = mbedtls_asn1_get_mpi(p, end, &ctx->N);
+    rc2 = mbedtls_asn1_get_mpi(p, end, &ctx->E);
+    if ((rc != 0) || (rc2 != 0)) {
         return -3;
     }
 
@@ -89,7 +87,8 @@
         return -4;
     }
 
-    if ((rc = mbedtls_rsa_check_pubkey(ctx)) != 0) {
+    rc = mbedtls_rsa_check_pubkey(ctx);
+    if (rc != 0) {
         return -5;
     }
 
diff --git a/bl2/ext/mcuboot/bootutil/src/image_validate.c b/bl2/ext/mcuboot/bootutil/src/image_validate.c
index 5b2b9a0..2dca5bd 100644
--- a/bl2/ext/mcuboot/bootutil/src/image_validate.c
+++ b/bl2/ext/mcuboot/bootutil/src/image_validate.c
@@ -28,16 +28,10 @@
 #include "bootutil/sha256.h"
 #include "bootutil/sign_key.h"
 
-#ifdef MCUBOOT_MYNEWT
-#include "mcuboot_config/mcuboot_config.h"
-#endif
-
 #ifdef MCUBOOT_SIGN_RSA
 #include "mbedtls/rsa.h"
 #endif
-#if defined(MCUBOOT_SIGN_EC) || defined(MCUBOOT_SIGN_EC256)
-#include "mbedtls/ecdsa.h"
-#endif
+
 #include "mbedtls/asn1.h"
 
 #include "bootutil_priv.h"
@@ -60,7 +54,7 @@
 
     /* in some cases (split image) the hash is seeded with data from
      * the loader image */
-    if(seed && (seed_len > 0)) {
+    if (seed && (seed_len > 0)) {
         bootutil_sha256_update(&sha256_ctx, seed, seed_len);
     }
 
@@ -96,18 +90,6 @@
 #if defined(MCUBOOT_SIGN_RSA)
 #    define EXPECTED_SIG_TLV IMAGE_TLV_RSA2048_PSS
 #    define EXPECTED_SIG_LEN(x) ((x) == 256) /* 2048 bits */
-#    if defined(MCUBOOT_SIGN_EC) || defined(MCUBOOT_SIGN_EC256)
-#        error "Multiple signature types not yet supported"
-#    endif
-#elif defined(MCUBOOT_SIGN_EC)
-#    define EXPECTED_SIG_TLV IMAGE_TLV_ECDSA224
-#    define EXPECTED_SIG_LEN(x) ((x) >= 64) /* oids + 2 * 28 bytes */
-#    if defined(MCUBOOT_SIGN_EC256)
-#        error "Multiple signature types not yet supported"
-#    endif
-#elif defined(MCUBOOT_SIGN_EC256)
-#    define EXPECTED_SIG_TLV IMAGE_TLV_ECDSA256
-#    define EXPECTED_SIG_LEN(x) ((x) >= 72) /* oids + 2 * 32 bytes */
 #endif
 
 #ifdef EXPECTED_SIG_TLV
@@ -153,7 +135,7 @@
 #endif
     struct image_tlv tlv;
     uint8_t buf[256];
-    uint8_t hash[32];
+    uint8_t hash[32] = {0};
     int rc;
 
     rc = bootutil_img_hash(hdr, fap, tmp_buf, tmp_buf_sz, hash,
@@ -185,7 +167,7 @@
      * and are able to do.
      */
     for (; off < end; off += sizeof(tlv) + tlv.it_len) {
-        rc = flash_area_read(fap, off, &tlv, sizeof tlv);
+        rc = flash_area_read(fap, off, &tlv, sizeof(tlv));
         if (rc) {
             return rc;
         }
@@ -198,7 +180,7 @@
             if (tlv.it_len != sizeof(hash)) {
                 return -1;
             }
-            rc = flash_area_read(fap, off + sizeof(tlv), buf, sizeof hash);
+            rc = flash_area_read(fap, off + sizeof(tlv), buf, sizeof(hash));
             if (rc) {
                 return rc;
             }
@@ -215,7 +197,7 @@
             if (tlv.it_len > 32) {
                 return -1;
             }
-            rc = flash_area_read(fap, off + sizeof tlv, buf, tlv.it_len);
+            rc = flash_area_read(fap, off + sizeof(tlv), buf, tlv.it_len);
             if (rc) {
                 return rc;
             }
@@ -237,7 +219,8 @@
             if (rc) {
                 return -1;
             }
-            rc = bootutil_verify_sig(hash, sizeof(hash), buf, tlv.it_len, key_id);
+            rc = bootutil_verify_sig(hash, sizeof(hash), buf, tlv.it_len,
+                                     key_id);
             if (rc == 0) {
                 valid_signature = 1;
             }
diff --git a/bl2/ext/mcuboot/bootutil/src/loader.c b/bl2/ext/mcuboot/bootutil/src/loader.c
index 30ac131..d091ec5 100644
--- a/bl2/ext/mcuboot/bootutil/src/loader.c
+++ b/bl2/ext/mcuboot/bootutil/src/loader.c
@@ -17,6 +17,12 @@
  * under the License.
  */
 
+/*
+ Original code taken from mcuboot project at:
+ https://github.com/runtimeco/mcuboot
+ Modifications are Copyright (c) 2018 Arm Limited.
+ */
+
 /**
  * This file provides an interface to the boot loader.  Functions defined in
  * this file should only be called while the boot loader is running.
@@ -37,10 +43,6 @@
 #define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_INFO
 #include "bootutil/bootutil_log.h"
 
-#ifdef MCUBOOT_MYNEWT
-#include "mcuboot_config/mcuboot_config.h"
-#endif
-
 static struct boot_loader_state boot_data;
 
 struct boot_status_table {
@@ -124,7 +126,7 @@
 };
 
 #define BOOT_STATUS_TABLES_COUNT \
-    (sizeof boot_status_tables / sizeof boot_status_tables[0])
+    (sizeof(boot_status_tables) / sizeof(boot_status_tables[0]))
 
 #define BOOT_LOG_SWAP_STATE(area, state)                            \
     BOOT_LOG_INF("%s: magic=%s, copy_done=0x%x, image_ok=0x%x",     \
@@ -136,11 +138,12 @@
                  (state)->image_ok)
 
 /**
- * Determines where in flash the most recent boot status is stored.  The boot
+ * Determines where in flash the most recent boot status is stored. The boot
  * status is necessary for completing a swap that was interrupted by a boot
  * loader reset.
  *
- * @return                      A BOOT_STATUS_SOURCE_[...] code indicating where *                                  status should be read from.
+ * @return  BOOT_STATUS_SOURCE_[...] code indicating where
+ *          status should be read from.
  */
 static int
 boot_status_source(void)
@@ -198,9 +201,9 @@
     post_swap_type = boot_swap_type();
 
     switch (post_swap_type) {
-    case BOOT_SWAP_TYPE_NONE   : return BOOT_SWAP_TYPE_PERM;
-    case BOOT_SWAP_TYPE_REVERT : return BOOT_SWAP_TYPE_TEST;
-    case BOOT_SWAP_TYPE_PANIC  : return BOOT_SWAP_TYPE_PANIC;
+    case BOOT_SWAP_TYPE_NONE:   return BOOT_SWAP_TYPE_PERM;
+    case BOOT_SWAP_TYPE_REVERT: return BOOT_SWAP_TYPE_TEST;
+    case BOOT_SWAP_TYPE_PANIC:  return BOOT_SWAP_TYPE_PANIC;
     }
 
     return BOOT_SWAP_TYPE_FAIL;
@@ -214,7 +217,7 @@
 static int
 boot_read_image_size(int slot, struct image_header *hdr, uint32_t *size)
 {
-    const struct flash_area *fap;
+    const struct flash_area *fap = NULL;
     struct image_tlv_info info;
     int area_id;
     int rc;
@@ -248,7 +251,7 @@
 static int
 boot_read_image_header(int slot, struct image_header *out_hdr)
 {
-    const struct flash_area *fap;
+    const struct flash_area *fap = NULL;
     int area_id;
     int rc;
 
@@ -259,7 +262,7 @@
         goto done;
     }
 
-    rc = flash_area_read(fap, 0, out_hdr, sizeof *out_hdr);
+    rc = flash_area_read(fap, 0, out_hdr, sizeof(*out_hdr));
     if (rc != 0) {
         rc = BOOT_EFLASH;
         goto done;
@@ -432,7 +435,7 @@
     int area_id;
     int rc;
 
-    memset(bs, 0, sizeof *bs);
+    memset(bs, 0, sizeof(*bs));
 
     status_loc = boot_status_source();
     switch (status_loc) {
@@ -474,7 +477,7 @@
 int
 boot_write_status(struct boot_status *bs)
 {
-    const struct flash_area *fap;
+    const struct flash_area *fap = NULL;
     uint32_t off;
     int area_id;
     int rc;
@@ -537,35 +540,6 @@
 }
 
 static int
-split_image_check(struct image_header *app_hdr,
-                  const struct flash_area *app_fap,
-                  struct image_header *loader_hdr,
-                  const struct flash_area *loader_fap)
-{
-    static void *tmpbuf;
-    uint8_t loader_hash[32];
-
-    if (!tmpbuf) {
-        tmpbuf = malloc(BOOT_TMPBUF_SZ);
-        if (!tmpbuf) {
-            return BOOT_ENOMEM;
-        }
-    }
-
-    if (bootutil_img_validate(loader_hdr, loader_fap, tmpbuf, BOOT_TMPBUF_SZ,
-                              NULL, 0, loader_hash)) {
-        return BOOT_EBADIMAGE;
-    }
-
-    if (bootutil_img_validate(app_hdr, app_fap, tmpbuf, BOOT_TMPBUF_SZ,
-                              loader_hash, 32, NULL)) {
-        return BOOT_EBADIMAGE;
-    }
-
-    return 0;
-}
-
-static int
 boot_validate_slot(int slot)
 {
     const struct flash_area *fap;
@@ -682,7 +656,7 @@
 static int
 boot_erase_sector(int flash_area_id, uint32_t off, uint32_t sz)
 {
-    const struct flash_area *fap;
+    const struct flash_area *fap = NULL;
     int rc;
 
     rc = flash_area_open(flash_area_id, &fap);
@@ -747,8 +721,8 @@
 
     bytes_copied = 0;
     while (bytes_copied < sz) {
-        if (sz - bytes_copied > sizeof buf) {
-            chunk_sz = sizeof buf;
+        if (sz - bytes_copied > sizeof(buf)) {
+            chunk_sz = sizeof(buf);
         } else {
             chunk_sz = sz - bytes_copied;
         }
@@ -1250,6 +1224,7 @@
      */
     static boot_sector_t slot0_sectors[BOOT_MAX_IMG_SECTORS];
     static boot_sector_t slot1_sectors[BOOT_MAX_IMG_SECTORS];
+
     boot_data.imgs[0].sectors = slot0_sectors;
     boot_data.imgs[1].sectors = slot1_sectors;
 
@@ -1289,7 +1264,8 @@
          * The following states need image_ok be explicitly set after the
          * swap was finished to avoid a new revert.
          */
-        if (swap_type == BOOT_SWAP_TYPE_REVERT || swap_type == BOOT_SWAP_TYPE_FAIL) {
+        if (swap_type == BOOT_SWAP_TYPE_REVERT ||
+            swap_type == BOOT_SWAP_TYPE_FAIL) {
 #ifndef MCUBOOT_OVERWRITE_ONLY
             rc = boot_set_image_ok();
             if (rc != 0) {
@@ -1337,7 +1313,8 @@
         assert(0);
 
         /* Loop forever... */
-        while (1) {}
+        while (1)
+            ;
     }
 
 #ifdef MCUBOOT_VALIDATE_SLOT0
@@ -1376,65 +1353,3 @@
     }
     return rc;
 }
-
-int
-split_go(int loader_slot, int split_slot, void **entry)
-{
-    boot_sector_t *sectors;
-    uintptr_t entry_val;
-    int loader_flash_id;
-    int split_flash_id;
-    int rc;
-
-    sectors = malloc(BOOT_MAX_IMG_SECTORS * 2 * sizeof *sectors);
-    if (sectors == NULL) {
-        return SPLIT_GO_ERR;
-    }
-    boot_data.imgs[loader_slot].sectors = sectors + 0;
-    boot_data.imgs[split_slot].sectors = sectors + BOOT_MAX_IMG_SECTORS;
-
-    loader_flash_id = flash_area_id_from_image_slot(loader_slot);
-    rc = flash_area_open(loader_flash_id,
-                         &BOOT_IMG_AREA(&boot_data, split_slot));
-    assert(rc == 0);
-    split_flash_id = flash_area_id_from_image_slot(split_slot);
-    rc = flash_area_open(split_flash_id,
-                         &BOOT_IMG_AREA(&boot_data, split_slot));
-    assert(rc == 0);
-
-    /* Determine the sector layout of the image slots and scratch area. */
-    rc = boot_read_sectors();
-    if (rc != 0) {
-        rc = SPLIT_GO_ERR;
-        goto done;
-    }
-
-    rc = boot_read_image_headers();
-    if (rc != 0) {
-        goto done;
-    }
-
-    /* Don't check the bootable image flag because we could really call a
-     * bootable or non-bootable image.  Just validate that the image check
-     * passes which is distinct from the normal check.
-     */
-    rc = split_image_check(boot_img_hdr(&boot_data, split_slot),
-                           BOOT_IMG_AREA(&boot_data, split_slot),
-                           boot_img_hdr(&boot_data, loader_slot),
-                           BOOT_IMG_AREA(&boot_data, loader_slot));
-    if (rc != 0) {
-        rc = SPLIT_GO_NON_MATCHING;
-        goto done;
-    }
-
-    entry_val = boot_img_slot_off(&boot_data, split_slot) +
-                boot_img_hdr(&boot_data, split_slot)->ih_hdr_size;
-    *entry = (void *) entry_val;
-    rc = SPLIT_GO_OK;
-
-done:
-    flash_area_close(BOOT_IMG_AREA(&boot_data, split_slot));
-    flash_area_close(BOOT_IMG_AREA(&boot_data, loader_slot));
-    free(sectors);
-    return rc;
-}
diff --git a/bl2/ext/mcuboot/flash_map.c b/bl2/ext/mcuboot/flash_map.c
index 899c5ad..0fb8b1a 100644
--- a/bl2/ext/mcuboot/flash_map.c
+++ b/bl2/ext/mcuboot/flash_map.c
@@ -17,14 +17,14 @@
  * under the License.
  */
 
-#include <zephyr.h>
-#include <flash.h>
+#include <errno.h>
+#include <stdbool.h>
 
 #include "target.h"
+#include <flash.h>
 
 #include <flash_map/flash_map.h>
 #include <hal/hal_flash.h>
-#include <sysflash/sysflash.h>
 
 #define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_INFO
 #include "bootutil/bootutil_log.h"
@@ -38,7 +38,7 @@
  * anything "real".
  */
 #define FLASH_DEVICE_ID 100
-#define FLASH_DEVICE_BASE CONFIG_FLASH_BASE_ADDRESS
+#define FLASH_DEVICE_BASE FLASH_BASE_ADDRESS
 
 #define FLASH_MAP_ENTRY_MAGIC 0xd00dbeef
 
@@ -140,12 +140,13 @@
     entry->ref_count--;
 }
 
-void zephyr_flash_area_warn_on_open(void)
+void flash_area_warn_on_open(void)
 {
     int i;
+    struct flash_map_entry *entry;
 
     for (i = 0; i < ARRAY_SIZE(part_map); i++) {
-        struct flash_map_entry *entry = &part_map[i];
+        entry = &part_map[i];
         if (entry->ref_count) {
             BOOT_LOG_WRN("area %u has %u users",
                          entry->area.fa_id, entry->ref_count);
@@ -160,8 +161,8 @@
     return flash_read(boot_flash_device, area->fa_off + off, dst, len);
 }
 
-int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
-             uint32_t len)
+int flash_area_write(const struct flash_area *area, uint32_t off,
+                     const void *src, uint32_t len)
 {
     int rc = 0;
 
@@ -197,19 +198,12 @@
     return slot + FLASH_AREA_IMAGE_0;
 }
 
-/*
- * This is used by the legacy file as well; don't mark it static until
- * that file is removed.
- */
-int flash_area_get_bounds(int idx, uint32_t *off, uint32_t *len)
+static int validate_idx(int idx, uint32_t *off, uint32_t *len)
 {
     /*
      * This simple layout has uniform slots, so just fill in the
      * right one.
      */
-    if (idx < FLASH_AREA_IMAGE_0 || idx > FLASH_AREA_IMAGE_SCRATCH) {
-        return -1;
-    }
 
     switch (idx) {
     case FLASH_AREA_IMAGE_0:
@@ -229,132 +223,92 @@
         return -1;
     }
 
-    BOOT_LOG_DBG("area %d: offset=0x%x, length=0x%x", idx, *off, *len);
+    BOOT_LOG_DBG("area %d: offset=0x%x, length=0x%x, sector size=0x%x",
+                 idx, *off, *len, FLASH_AREA_IMAGE_SECTOR_SIZE);
     return 0;
 }
 
-/*
- * The legacy fallbacks are used instead if the flash driver doesn't
- * provide page layout support.
- */
-#if defined(CONFIG_FLASH_PAGE_LAYOUT)
-struct layout_data {
-    uint32_t area_idx;
-    uint32_t area_off;
-    uint32_t area_len;
-    void *ret;        /* struct flash_area* or struct flash_sector* */
-    uint32_t ret_idx;
-    uint32_t ret_len;
-    int status;
-};
-
-/*
- * Generic page layout discovery routine. This is kept separate to
- * support both the deprecated flash_area_to_sectors() and the current
- * flash_area_get_sectors(). A lot of this can be inlined once
- * flash_area_to_sectors() is removed.
- */
-static int flash_area_layout(int idx, int *cnt, void *ret,
-                             flash_page_cb cb, struct layout_data *cb_data)
-{
-    cb_data->area_idx = idx;
-    if (flash_area_get_bounds(idx, &cb_data->area_off, &cb_data->area_len)) {
-        return -1;
-    }
-    cb_data->ret = ret;
-    cb_data->ret_idx = 0;
-    cb_data->ret_len = *cnt;
-    cb_data->status = 0;
-
-    flash_page_foreach(boot_flash_device, cb, cb_data);
-
-    if (cb_data->status == 0) {
-        *cnt = cb_data->ret_idx;
-    }
-
-    return cb_data->status;
-}
-
-/*
- * Check if a flash_page_foreach() callback should exit early, due to
- * one of the following conditions:
- *
- * - The flash page described by "info" is before the area of interest
- *   described in "data"
- * - The flash page is after the end of the area
- * - There are too many flash pages on the device to fit in the array
- *   held in data->ret. In this case, data->status is set to -ENOMEM.
- *
- * The value to return to flash_page_foreach() is stored in
- * "bail_value" if the callback should exit early.
- */
-static bool should_bail(const struct flash_pages_info *info,
-                        struct layout_data *data,
-                        bool *bail_value)
-{
-    if (info->start_offset < data->area_off) {
-        *bail_value = true;
-        return true;
-    } else if (info->start_offset >= data->area_off + data->area_len) {
-        *bail_value = false;
-        return true;
-    } else if (data->ret_idx >= data->ret_len) {
-        data->status = -ENOMEM;
-        *bail_value = false;
-        return true;
-    }
-
-    return false;
-}
-
-static bool to_sectors_cb(const struct flash_pages_info *info, void *datav)
-{
-    struct layout_data *data = datav;
-    struct flash_area *ret = data->ret;
-    bool bail;
-
-    if (should_bail(info, data, &bail)) {
-        return bail;
-    }
-
-    ret[data->ret_idx].fa_id = data->area_idx;
-    ret[data->ret_idx].fa_device_id = 0;
-    ret[data->ret_idx].pad16 = 0;
-    ret[data->ret_idx].fa_off = info->start_offset;
-    ret[data->ret_idx].fa_size = info->size;
-    data->ret_idx++;
-
-    return true;
-}
-
 int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
 {
-    struct layout_data data;
+    uint32_t off;
+    uint32_t len;
+    uint32_t max_cnt = *cnt;
+    uint32_t rem_len;
 
-    return flash_area_layout(idx, cnt, ret, to_sectors_cb, &data);
-}
-
-static bool get_sectors_cb(const struct flash_pages_info *info, void *datav)
-{
-    struct layout_data *data = datav;
-    struct flash_sector *ret = data->ret;
-    bool bail;
-
-    if (should_bail(info, data, &bail)) {
-        return bail;
+    if (validate_idx(idx, &off, &len)) {
+        return -1;
     }
 
-    ret[data->ret_idx].fs_off = info->start_offset - data->area_off;
-    ret[data->ret_idx].fs_size = info->size;
-    data->ret_idx++;
+    if (*cnt < 1) {
+        return -1;
+    }
 
-    return true;
+    rem_len = len;
+    *cnt = 0;
+    while (rem_len > 0 && *cnt < max_cnt) {
+        if (rem_len < FLASH_AREA_IMAGE_SECTOR_SIZE) {
+            BOOT_LOG_ERR("area %d size 0x%x not divisible by sector size 0x%x",
+                     idx, len, FLASH_AREA_IMAGE_SECTOR_SIZE);
+            return -1;
+        }
+
+        ret[*cnt].fa_id = idx;
+        ret[*cnt].fa_device_id = 0;
+        ret[*cnt].pad16 = 0;
+        ret[*cnt].fa_off = off + (FLASH_AREA_IMAGE_SECTOR_SIZE * (*cnt));
+        ret[*cnt].fa_size = FLASH_AREA_IMAGE_SECTOR_SIZE;
+        *cnt = *cnt + 1;
+        rem_len -= FLASH_AREA_IMAGE_SECTOR_SIZE;
+    }
+
+    if (*cnt >= max_cnt) {
+        BOOT_LOG_ERR("flash area %d sector count overflow", idx);
+        return -1;
+    }
+
+    return 0;
 }
 
+/*
+ * Lookup the sector map for a given flash area.  This should fill in
+ * `ret` with all of the sectors in the area.  `*cnt` will be set to
+ * the storage at `ret` and should be set to the final number of
+ * sectors in this area.
+ */
 int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret)
 {
-    struct layout_data data;
+    uint32_t off;
+    uint32_t len;
+    uint32_t max_cnt = *cnt;
+    uint32_t rem_len;
 
-    return flash_area_layout(idx, cnt, ret, get_sectors_cb, &data);
+    if (validate_idx(idx, &off, &len)) {
+        return -1;
+    }
+
+    if (*cnt < 1) {
+        return -1;
+    }
+
+    rem_len = len;
+    *cnt = 0;
+    while (rem_len > 0 && *cnt < max_cnt) {
+        if (rem_len < FLASH_AREA_IMAGE_SECTOR_SIZE) {
+            BOOT_LOG_ERR("area %d size 0x%x not divisible by sector size 0x%x",
+                         idx, len, FLASH_AREA_IMAGE_SECTOR_SIZE);
+            return -1;
+        }
+
+        ret[*cnt].fs_off = FLASH_AREA_IMAGE_SECTOR_SIZE * (*cnt);
+        ret[*cnt].fs_size = FLASH_AREA_IMAGE_SECTOR_SIZE;
+        *cnt = *cnt + 1;
+        rem_len -= FLASH_AREA_IMAGE_SECTOR_SIZE;
+    }
+
+    if (*cnt >= max_cnt) {
+        BOOT_LOG_ERR("flash area %d sector count overflow", idx);
+        return -1;
+    }
+
+    return 0;
 }
-#endif /* defined(CONFIG_FLASH_PAGE_LAYOUT) */
diff --git a/bl2/ext/mcuboot/hal_flash.c b/bl2/ext/mcuboot/hal_flash.c
index 17b6124..60d9271 100644
--- a/bl2/ext/mcuboot/hal_flash.c
+++ b/bl2/ext/mcuboot/hal_flash.c
@@ -17,8 +17,6 @@
  * under the License.
  */
 
-#include <zephyr.h>
-
 #include "target.h"
 
 #include "hal/hal_flash.h"
diff --git a/bl2/ext/mcuboot/include/bl2_util.h b/bl2/ext/mcuboot/include/bl2_util.h
new file mode 100644
index 0000000..334c2a0
--- /dev/null
+++ b/bl2/ext/mcuboot/include/bl2_util.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011-2014, Wind River Systems, Inc.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __BL2_UTIL_H__
+#define __BL2_UTIL_H__
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#include <stddef.h>
+
+    /* Evaluates to 0 if cond is true-ish; compile error otherwise */
+#define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
+
+    /* Evaluates to 0 if array is an array; compile error if not array (e.g.
+     * pointer)
+     */
+#define IS_ARRAY(array) \
+        ZERO_OR_COMPILE_ERROR(!__builtin_types_compatible_p(__typeof__(array), \
+                              __typeof__(&(array)[0])))
+
+#define ARRAY_SIZE(array) \
+    ((unsigned long) (IS_ARRAY(array) + \
+        (sizeof(array) / sizeof((array)[0]))))
+
+#define CONTAINER_OF(ptr, type, field) \
+        ((type *)(((char *)(ptr)) - offsetof(type, field)))
+
+struct device {
+    int device_id;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BL2_UTIL_H__ */
+
diff --git a/bl2/ext/mcuboot/include/config-boot.h b/bl2/ext/mcuboot/include/config-boot.h
index a81a02f..44dbac1 100644
--- a/bl2/ext/mcuboot/include/config-boot.h
+++ b/bl2/ext/mcuboot/include/config-boot.h
@@ -23,7 +23,7 @@
 /*
  * Minimal configuration for using TLS in the bootloader
  *
- * - RSA or ECDSA signature verification
+ * - RSA signature verification
  */
 
 #ifndef MBEDTLS_CONFIG_BOOT_H
@@ -55,16 +55,6 @@
 #define MBEDTLS_TEST_NULL_ENTROPY
 #endif
 
-/* mbed TLS feature support */
-#ifdef CONFIG_BOOT_VERIFY_ECDSA_SIGNATURE
-#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
-#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
-#define MBEDTLS_ECP_NIST_OPTIM
-#define MBEDTLS_ECDSA_C
-#define MBEDTLS_ECDH_C
-#define MBEDTLS_ECP_C
-#endif
-
 #ifdef CONFIG_BOOT_VERIFY_RSA_SIGNATURE
 #define MBEDTLS_RSA_C
 #define MBEDTLS_PKCS1_V15
diff --git a/bl2/ext/mcuboot/include/flash_map/flash_map.h b/bl2/ext/mcuboot/include/flash_map/flash_map.h
index 506f266..2eba8e2 100644
--- a/bl2/ext/mcuboot/include/flash_map/flash_map.h
+++ b/bl2/ext/mcuboot/include/flash_map/flash_map.h
@@ -17,6 +17,12 @@
  * under the License.
  */
 
+/*
+ Original code taken from mcuboot project at:
+ https://github.com/runtimeco/mcuboot
+ Modifications are Copyright (c) 2018 Arm Limited.
+ */
+
 #ifndef H_UTIL_FLASH_MAP_
 #define H_UTIL_FLASH_MAP_
 
@@ -43,6 +49,10 @@
  */
 #include <inttypes.h>
 
+#define FLASH_AREA_IMAGE_0       1
+#define FLASH_AREA_IMAGE_1       2
+#define FLASH_AREA_IMAGE_SCRATCH 3
+
 /**
  * @brief Structure describing an area on a flash device.
  *
@@ -107,23 +117,25 @@
 /*
  * Start using flash area.
  */
-int flash_area_open(uint8_t id, const struct flash_area **);
+int flash_area_open(uint8_t id, const struct flash_area **area);
 
-void flash_area_close(const struct flash_area *);
+void flash_area_close(const struct flash_area *area);
 
 /*
  * Read/write/erase. Offset is relative from beginning of flash area.
  */
-int flash_area_read(const struct flash_area *, uint32_t off, void *dst,
-  uint32_t len);
-int flash_area_write(const struct flash_area *, uint32_t off, const void *src,
-  uint32_t len);
-int flash_area_erase(const struct flash_area *, uint32_t off, uint32_t len);
+int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
+                    uint32_t len);
+
+int flash_area_write(const struct flash_area *area, uint32_t off,
+                     const void *src, uint32_t len);
+
+int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len);
 
 /*
  * Alignment restriction for flash writes.
  */
-uint8_t flash_area_align(const struct flash_area *);
+uint8_t flash_area_align(const struct flash_area *area);
 
 /*
  * Given flash area ID, return info about sectors within the area.
@@ -140,6 +152,7 @@
 
 int flash_area_id_from_image_slot(int slot);
 int flash_area_id_to_image_slot(int area_id);
+void flash_area_warn_on_open(void);
 
 #ifdef __cplusplus
 }
diff --git a/bl2/ext/mcuboot/include/target.h b/bl2/ext/mcuboot/include/target.h
index 9ccc032..6f85e5b 100644
--- a/bl2/ext/mcuboot/include/target.h
+++ b/bl2/ext/mcuboot/include/target.h
@@ -7,41 +7,9 @@
 #define H_TARGETS_TARGET_
 
 #if defined(MCUBOOT_TARGET_CONFIG)
-/*
- * Target-specific definitions are permitted in legacy cases that
- * don't provide the information via DTS, etc.
- */
 #include MCUBOOT_TARGET_CONFIG
 #else
-/*
- * Otherwise, the Zephyr SoC header and the DTS provide most
- * everything we need.
- */
-#include <soc.h>
-
-#define FLASH_ALIGN FLASH_WRITE_BLOCK_SIZE
-
-/*
- * TODO: remove soc_family_kinetis.h once its flash driver supports
- * FLASH_PAGE_LAYOUT.
- */
-#if defined(CONFIG_SOC_FAMILY_KINETIS)
-#include "soc_family_kinetis.h"
-#endif
-#endif /* !defined(MCUBOOT_TARGET_CONFIG) */
-
-/*
- * Sanity check the target support.
- */
-#if !defined(FLASH_DRIVER_NAME) || \
-    !defined(FLASH_ALIGN) ||                  \
-    !defined(FLASH_AREA_IMAGE_0_OFFSET) || \
-    !defined(FLASH_AREA_IMAGE_0_SIZE) || \
-    !defined(FLASH_AREA_IMAGE_1_OFFSET) || \
-    !defined(FLASH_AREA_IMAGE_1_SIZE) || \
-    !defined(FLASH_AREA_IMAGE_SCRATCH_OFFSET) || \
-    !defined(FLASH_AREA_IMAGE_SCRATCH_SIZE)
-#error "Target support is incomplete; cannot build mcuboot."
+#error "Board is currently not supported by bootloader"
 #endif
 
 #endif
diff --git a/bl2/ext/mcuboot/include/util.h b/bl2/ext/mcuboot/include/util.h
deleted file mode 100644
index ba29386..0000000
--- a/bl2/ext/mcuboot/include/util.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (c) 2011-2014, Wind River Systems, Inc.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/**
- * @file
- * @brief Misc utilities
- *
- * Misc utilities usable by the kernel and application code.
- */
-
-#ifndef _UTIL__H_
-#define _UTIL__H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ASMLANGUAGE
-
-#include <zephyr/types.h>
-
-/* Helper to pass a int as a pointer or vice-versa.
- * Those are available for 32 bits architectures:
- */
-#define POINTER_TO_UINT(x) ((u32_t) (x))
-#define UINT_TO_POINTER(x) ((void *) (x))
-#define POINTER_TO_INT(x)  ((s32_t) (x))
-#define INT_TO_POINTER(x)  ((void *) (x))
-
-/* Evaluates to 0 if cond is true-ish; compile error otherwise */
-#define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
-
-/* Evaluates to 0 if array is an array; compile error if not array (e.g.
- * pointer)
- */
-#define IS_ARRAY(array) \
-	ZERO_OR_COMPILE_ERROR( \
-		!__builtin_types_compatible_p(__typeof__(array), \
-					      __typeof__(&(array)[0])))
-
-/* Evaluates to number of elements in an array; compile error if not
- * an array (e.g. pointer)
- */
-#define ARRAY_SIZE(array) \
-	((unsigned long) (IS_ARRAY(array) + \
-		(sizeof(array) / sizeof((array)[0]))))
-
-/* Evaluates to 1 if ptr is part of array, 0 otherwise; compile error if
- * "array" argument is not an array (e.g. "ptr" and "array" mixed up)
- */
-#define PART_OF_ARRAY(array, ptr) \
-	((ptr) && ((ptr) >= &array[0] && (ptr) < &array[ARRAY_SIZE(array)]))
-
-#define CONTAINER_OF(ptr, type, field) \
-	((type *)(((char *)(ptr)) - offsetof(type, field)))
-
-/* round "x" up/down to next multiple of "align" (which must be a power of 2) */
-#define ROUND_UP(x, align)                                   \
-	(((unsigned long)(x) + ((unsigned long)align - 1)) & \
-	 ~((unsigned long)align - 1))
-#define ROUND_DOWN(x, align) ((unsigned long)(x) & ~((unsigned long)align - 1))
-
-#define ceiling_fraction(numerator, divider) \
-	(((numerator) + ((divider) - 1)) / (divider))
-
-#ifdef INLINED
-#define INLINE inline
-#else
-#define INLINE
-#endif
-
-#ifndef max
-#define max(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef min
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-static inline int is_power_of_two(unsigned int x)
-{
-	return (x != 0) && !(x & (x - 1));
-}
-
-static inline s64_t arithmetic_shift_right(s64_t value, u8_t shift)
-{
-	s64_t sign_ext;
-
-	if (shift == 0) {
-		return value;
-	}
-
-	/* extract sign bit */
-	sign_ext = (value >> 63) & 1;
-
-	/* make all bits of sign_ext be the same as the value's sign bit */
-	sign_ext = -sign_ext;
-
-	/* shift value and fill opened bit positions with sign bit */
-	return (value >> shift) | (sign_ext << (64 - shift));
-}
-
-#endif /* !_ASMLANGUAGE */
-
-/* KB, MB, GB */
-#define KB(x) ((x) << 10)
-#define MB(x) (KB(x) << 10)
-#define GB(x) (MB(x) << 10)
-
-/* KHZ, MHZ */
-#define KHZ(x) ((x) * 1000)
-#define MHZ(x) (KHZ(x) * 1000)
-
-#ifndef BIT
-#define BIT(n)  (1UL << (n))
-#endif
-
-#define BIT_MASK(n) (BIT(n) - 1)
-
-/**
- * @brief Check for macro definition in compiler-visible expressions
- *
- * This trick was pioneered in Linux as the config_enabled() macro.
- * The madness has the effect of taking a macro value that may be
- * defined to "1" (e.g. CONFIG_MYFEATURE), or may not be defined at
- * all and turning it into a literal expression that can be used at
- * "runtime".  That is, it works similarly to
- * "defined(CONFIG_MYFEATURE)" does except that it is an expansion
- * that can exist in a standard expression and be seen by the compiler
- * and optimizer.  Thus much ifdef usage can be replaced with cleaner
- * expressions like:
- *
- *     if (IS_ENABLED(CONFIG_MYFEATURE))
- *             myfeature_enable();
- *
- * INTERNAL
- * First pass just to expand any existing macros, we need the macro
- * value to be e.g. a literal "1" at expansion time in the next macro,
- * not "(1)", etc...  Standard recursive expansion does not work.
- */
-#define IS_ENABLED(config_macro) _IS_ENABLED1(config_macro)
-
-/* Now stick on a "_XXXX" prefix, it will now be "_XXXX1" if config_macro
- * is "1", or just "_XXXX" if it's undefined.
- *   ENABLED:   _IS_ENABLED2(_XXXX1)
- *   DISABLED   _IS_ENABLED2(_XXXX)
- */
-#define _IS_ENABLED1(config_macro) _IS_ENABLED2(_XXXX##config_macro)
-
-/* Here's the core trick, we map "_XXXX1" to "_YYYY," (i.e. a string
- * with a trailing comma), so it has the effect of making this a
- * two-argument tuple to the preprocessor only in the case where the
- * value is defined to "1"
- *   ENABLED:    _YYYY,    <--- note comma!
- *   DISABLED:   _XXXX
- */
-#define _XXXX1 _YYYY,
-
-/* Then we append an extra argument to fool the gcc preprocessor into
- * accepting it as a varargs macro.
- *                         arg1   arg2  arg3
- *   ENABLED:   _IS_ENABLED3(_YYYY,    1,    0)
- *   DISABLED   _IS_ENABLED3(_XXXX 1,  0)
- */
-#define _IS_ENABLED2(one_or_two_args) _IS_ENABLED3(one_or_two_args 1, 0)
-
-/* And our second argument is thus now cooked to be 1 in the case
- * where the value is defined to 1, and 0 if not:
- */
-#define _IS_ENABLED3(ignore_this, val, ...) val
-
-/**
- * Macros for doing code-generation with the preprocessor.
- *
- * Generally it is better to generate code with the preprocessor than
- * to copy-paste code or to generate code with the build system /
- * python script's etc.
- *
- * http://stackoverflow.com/a/12540675
- */
-#define UTIL_EMPTY(...)
-#define UTIL_DEFER(...) __VA_ARGS__ UTIL_EMPTY()
-#define UTIL_OBSTRUCT(...) __VA_ARGS__ UTIL_DEFER(UTIL_EMPTY)()
-#define UTIL_EXPAND(...) __VA_ARGS__
-
-#define UTIL_EVAL(...)  UTIL_EVAL1(UTIL_EVAL1(UTIL_EVAL1(__VA_ARGS__)))
-#define UTIL_EVAL1(...) UTIL_EVAL2(UTIL_EVAL2(UTIL_EVAL2(__VA_ARGS__)))
-#define UTIL_EVAL2(...) UTIL_EVAL3(UTIL_EVAL3(UTIL_EVAL3(__VA_ARGS__)))
-#define UTIL_EVAL3(...) UTIL_EVAL4(UTIL_EVAL4(UTIL_EVAL4(__VA_ARGS__)))
-#define UTIL_EVAL4(...) UTIL_EVAL5(UTIL_EVAL5(UTIL_EVAL5(__VA_ARGS__)))
-#define UTIL_EVAL5(...) __VA_ARGS__
-
-#define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__)
-#define UTIL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
-
-#define UTIL_INC(x) UTIL_PRIMITIVE_CAT(UTIL_INC_, x)
-#define UTIL_INC_0 1
-#define UTIL_INC_1 2
-#define UTIL_INC_2 3
-#define UTIL_INC_3 4
-#define UTIL_INC_4 5
-#define UTIL_INC_5 6
-#define UTIL_INC_6 7
-#define UTIL_INC_7 8
-#define UTIL_INC_8 9
-#define UTIL_INC_9 10
-#define UTIL_INC_10 11
-#define UTIL_INC_11 12
-#define UTIL_INC_12 13
-#define UTIL_INC_13 14
-#define UTIL_INC_14 15
-#define UTIL_INC_15 16
-#define UTIL_INC_16 17
-#define UTIL_INC_17 18
-#define UTIL_INC_18 19
-#define UTIL_INC_19 19
-
-#define UTIL_DEC(x) UTIL_PRIMITIVE_CAT(UTIL_DEC_, x)
-#define UTIL_DEC_0 0
-#define UTIL_DEC_1 0
-#define UTIL_DEC_2 1
-#define UTIL_DEC_3 2
-#define UTIL_DEC_4 3
-#define UTIL_DEC_5 4
-#define UTIL_DEC_6 5
-#define UTIL_DEC_7 6
-#define UTIL_DEC_8 7
-#define UTIL_DEC_9 8
-#define UTIL_DEC_10 9
-#define UTIL_DEC_11 10
-#define UTIL_DEC_12 11
-#define UTIL_DEC_13 12
-#define UTIL_DEC_14 13
-#define UTIL_DEC_15 14
-#define UTIL_DEC_16 15
-#define UTIL_DEC_17 16
-#define UTIL_DEC_18 17
-#define UTIL_DEC_19 18
-
-#define UTIL_CHECK_N(x, n, ...) n
-#define UTIL_CHECK(...) UTIL_CHECK_N(__VA_ARGS__, 0,)
-
-#define UTIL_NOT(x) UTIL_CHECK(UTIL_PRIMITIVE_CAT(UTIL_NOT_, x))
-#define UTIL_NOT_0 ~, 1,
-
-#define UTIL_COMPL(b) UTIL_PRIMITIVE_CAT(UTIL_COMPL_, b)
-#define UTIL_COMPL_0 1
-#define UTIL_COMPL_1 0
-
-#define UTIL_BOOL(x) UTIL_COMPL(UTIL_NOT(x))
-
-#define UTIL_IIF(c) UTIL_PRIMITIVE_CAT(UTIL_IIF_, c)
-#define UTIL_IIF_0(t, ...) __VA_ARGS__
-#define UTIL_IIF_1(t, ...) t
-
-#define UTIL_IF(c) UTIL_IIF(UTIL_BOOL(c))
-
-#define UTIL_EAT(...)
-#define UTIL_EXPAND(...) __VA_ARGS__
-#define UTIL_WHEN(c) UTIL_IF(c)(UTIL_EXPAND, UTIL_EAT)
-
-#define UTIL_REPEAT(count, macro, ...)			    \
-	UTIL_WHEN(count)				    \
-	(						    \
-		UTIL_OBSTRUCT(UTIL_REPEAT_INDIRECT) ()	    \
-		(					    \
-			UTIL_DEC(count), macro, __VA_ARGS__ \
-		)					    \
-		UTIL_OBSTRUCT(macro)			    \
-		(					    \
-			UTIL_DEC(count), __VA_ARGS__	    \
-		)					    \
-	)
-#define UTIL_REPEAT_INDIRECT() UTIL_REPEAT
-
-/**
- * Generates a sequence of code.
- * Useful for generating code like;
- *
- * NRF_PWM0, NRF_PWM1, NRF_PWM2,
- *
- * @arg LEN: The length of the sequence. Must be defined and less than
- * 20.
- *
- * @arg F(i, F_ARG): A macro function that accepts two arguments.
- *  F is called repeatedly, the first argument
- *  is the index in the sequence, and the second argument is the third
- *  argument given to UTIL_LISTIFY.
- *
- * Example:
- *
- *    \#define FOO(i, _) NRF_PWM ## i ,
- *    { UTIL_LISTIFY(PWM_COUNT, FOO) }
- *    // The above two lines will generate the below:
- *    { NRF_PWM0 , NRF_PWM1 , }
- *
- * @note Calling UTIL_LISTIFY with undefined arguments has undefined
- * behaviour.
- */
-#define UTIL_LISTIFY(LEN, F, F_ARG) UTIL_EVAL(UTIL_REPEAT(LEN, F, F_ARG))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _UTIL__H_ */
diff --git a/bl2/ext/mcuboot/keys.c b/bl2/ext/mcuboot/keys.c
index 56b78df..7bad135 100644
--- a/bl2/ext/mcuboot/keys.c
+++ b/bl2/ext/mcuboot/keys.c
@@ -46,26 +46,11 @@
     0xc9, 0x02, 0x03, 0x01, 0x00, 0x01
 };
 const unsigned int root_pub_der_len = 270;
-#elif defined(MCUBOOT_SIGN_EC256)
-const unsigned char root_pub_der[] = {
-    0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
-    0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
-    0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
-    0x42, 0x00, 0x04, 0x2a, 0xcb, 0x40, 0x3c, 0xe8,
-    0xfe, 0xed, 0x5b, 0xa4, 0x49, 0x95, 0xa1, 0xa9,
-    0x1d, 0xae, 0xe8, 0xdb, 0xbe, 0x19, 0x37, 0xcd,
-    0x14, 0xfb, 0x2f, 0x24, 0x57, 0x37, 0xe5, 0x95,
-    0x39, 0x88, 0xd9, 0x94, 0xb9, 0xd6, 0x5a, 0xeb,
-    0xd7, 0xcd, 0xd5, 0x30, 0x8a, 0xd6, 0xfe, 0x48,
-    0xb2, 0x4a, 0x6a, 0x81, 0x0e, 0xe5, 0xf0, 0x7d,
-    0x8b, 0x68, 0x34, 0xcc, 0x3a, 0x6a, 0xfc, 0x53,
-    0x8e, 0xfa, 0xc1, };
-const unsigned int root_pub_der_len = 91;
 #else
 #error "No public key available for given signing algorithm."
 #endif
 
-#if defined(MCUBOOT_SIGN_RSA) || defined(MCUBOOT_SIGN_EC256)
+#if defined(MCUBOOT_SIGN_RSA)
 const struct bootutil_key bootutil_keys[] = {
     {
         .key = root_pub_der,
diff --git a/bl2/ext/mcuboot/os.c b/bl2/ext/mcuboot/os.c
index 0a5abbd..153b335 100644
--- a/bl2/ext/mcuboot/os.c
+++ b/bl2/ext/mcuboot/os.c
@@ -17,12 +17,16 @@
  * under the License.
  */
 
-#include <zephyr.h>
+/*
+ Original code taken from mcuboot project at:
+ https://github.com/runtimeco/mcuboot
+ Modifications are Copyright (c) 2018 Arm Limited.
+ */
+
+#include <stdlib.h>
 #include <string.h>
 
 #include "os/os_heap.h"
-
-#define MBEDTLS_CONFIG_FILE CONFIG_MBEDTLS_CFG_FILE
 #include <mbedtls/platform.h>
 
 /* D(void *os_malloc(size_t size)) */
@@ -31,7 +35,8 @@
     /* Note that this doesn't check for overflow.  Assume the
      * calls only come from within the app. */
     size_t total = nelem * size;
-    void *buf = k_malloc(total);
+    void *buf = malloc(total);
+
     if (buf) {
         memset(buf, 0, total);
     }
@@ -40,7 +45,7 @@
 
 void os_free(void *ptr)
 {
-    k_free(ptr);
+    free(ptr);
 }
 
 /*
diff --git a/bl2/ext/mcuboot/scripts/assemble.py b/bl2/ext/mcuboot/scripts/assemble.py
index 7a38985..1523964 100644
--- a/bl2/ext/mcuboot/scripts/assemble.py
+++ b/bl2/ext/mcuboot/scripts/assemble.py
@@ -1,6 +1,7 @@
 #! /usr/bin/env python3
 #
 # Copyright 2017 Linaro Limited
+# Copyright (c) 2017, Arm Limited.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -22,24 +23,15 @@
 import errno
 import io
 import re
-import os.path
+import os
+import shutil
 
-def same_keys(a, b):
-    """Determine if the dicts a and b have the same keys in them"""
-    for ak in a.keys():
-        if ak not in b:
-            return False
-    for bk in b.keys():
-        if bk not in a:
-            return False
-    return True
-
-offset_re = re.compile(r"^#define FLASH_AREA_([0-9A-Z_]+)_OFFSET_0\s+((0x)?[0-9a-fA-F]+)")
-size_re   = re.compile(r"^#define FLASH_AREA_([0-9A-Z_]+)_SIZE_0\s+((0x)?[0-9a-fA-F]+)")
+offset_re = re.compile(r"^#define ([0-9A-Z_]+)_IMAGE_OFFSET\s+((0x)?[0-9a-fA-F]+)")
+size_re   = re.compile(r"^#define ([0-9A-Z_]+)_IMAGE_MAX_SIZE\s+((0x)?[0-9a-fA-F]+)")
 
 class Assembly():
-    def __init__(self, output, bootdir):
-        self.find_slots(bootdir)
+    def __init__(self, output):
+        self.find_slots()
         try:
             os.unlink(output)
         except OSError as e:
@@ -47,10 +39,15 @@
                 raise
         self.output = output
 
-    def find_slots(self, bootdir):
+    def find_slots(self):
         offsets = {}
         sizes = {}
-        with open(os.path.join(bootdir, 'include', 'generated', 'generated_dts_board.h'), 'r') as fd:
+
+        scriptsDir = os.path.dirname(os.path.abspath(__file__))
+        path = '../../../../platform/ext/target/sse_200_mps2/sse_200/partition/flash_layout.h'
+        configFile = os.path.join(scriptsDir, path)
+
+        with open(configFile, 'r') as fd:
             for line in fd:
                 m = offset_re.match(line)
                 if m is not None:
@@ -59,18 +56,11 @@
                 if m is not None:
                     sizes[m.group(1)] = int(m.group(2), 0)
 
-        if not same_keys(offsets, sizes):
-            raise Exception("Inconsistent data in generated_dts_board.h")
+        if 'SECURE' not in offsets:
+            raise Exception("Image config does not have secure partition")
 
-        # We care about the MCUBOOT, IMAGE_0, and IMAGE_1 partitions.
-        if 'MCUBOOT' not in offsets:
-            raise Exception("Board partition table does not have mcuboot partition")
-
-        if 'IMAGE_0' not in offsets:
-            raise Exception("Board partition table does not have image-0 partition")
-
-        if 'IMAGE_1' not in offsets:
-            raise Exception("Board partition table does not have image-1 partition")
+        if 'NON_SECURE' not in offsets:
+            raise Exception("Image config does not have non-secure partition")
 
         self.offsets = offsets
         self.sizes = sizes
@@ -78,37 +68,32 @@
     def add_image(self, source, partition):
         with open(self.output, 'ab') as ofd:
             pos = ofd.tell()
-            print("partition {}, pos={}, offset={}".format(partition, pos, self.offsets[partition]))
             if pos > self.offsets[partition]:
                 raise Exception("Partitions not in order, unsupported")
             if pos < self.offsets[partition]:
-                buf = b'\xFF' * (self.offsets[partition] - pos)
-                ofd.write(buf)
+                ofd.write(b'\xFF' * (self.offsets[partition] - pos))
+            statinfo = os.stat(source)
+            if statinfo.st_size > self.sizes[partition]:
+                raise Exception("Image {} is too large for partition".format(source))
             with open(source, 'rb') as rfd:
-                ibuf = rfd.read()
-                if len(ibuf) > self.sizes[partition]:
-                    raise Exception("Image {} is too large for partition".format(source))
-            ofd.write(ibuf)
+                shutil.copyfileobj(rfd, ofd, 0x10000)
 
 def main():
     parser = argparse.ArgumentParser()
 
-    parser.add_argument('-b', '--bootdir', required=True,
-            help='Directory of built bootloader')
-    parser.add_argument('-p', '--primary', required=True,
-            help='Signed image file for primary image')
-    parser.add_argument('-s', '--secondary',
-            help='Signed image file for secondary image')
+    parser.add_argument('-s', '--secure', required=True,
+            help='Unsigned secure image')
+    parser.add_argument('-n', '--non_secure',
+            help='Unsigned non-secure image')
     parser.add_argument('-o', '--output', required=True,
             help='Filename to write full image to')
 
     args = parser.parse_args()
-    output = Assembly(args.output, args.bootdir)
+    output = Assembly(args.output)
 
-    output.add_image(os.path.join(args.bootdir, "zephyr.bin"), 'MCUBOOT')
-    output.add_image(args.primary, "IMAGE_0")
-    if args.secondary is not None:
-        output.add_image(args.secondary, "IMAGE_1")
+
+    output.add_image(args.secure, "SECURE")
+    output.add_image(args.non_secure, "NON_SECURE")
 
 if __name__ == '__main__':
     main()
diff --git a/bl2/ext/mcuboot/scripts/imgtool.py b/bl2/ext/mcuboot/scripts/imgtool.py
index bc67252..9420d2b 100644
--- a/bl2/ext/mcuboot/scripts/imgtool.py
+++ b/bl2/ext/mcuboot/scripts/imgtool.py
@@ -22,15 +22,9 @@
 
 def gen_rsa2048(args):
     keys.RSA2048.generate().export_private(args.key)
-def gen_ecdsa_p256(args):
-    keys.ECDSA256P1.generate().export_private(args.key)
-def gen_ecdsa_p224(args):
-    print("TODO: p-224 not yet implemented")
 
 keygens = {
-        'rsa-2048': gen_rsa2048,
-        'ecdsa-p256': gen_ecdsa_p256,
-        'ecdsa-p224': gen_ecdsa_p224, }
+        'rsa-2048': gen_rsa2048, }
 
 def do_keygen(args):
     if args.type not in keygens:
@@ -42,10 +36,8 @@
     key = keys.load(args.key)
     if args.lang == 'c':
         key.emit_c()
-    elif args.lang == 'rust':
-        key.emit_rust()
     else:
-        msg = "Unsupported language, valid are: c, or rust"
+        msg = "Unsupported language, valid are: c"
         raise argparse.ArgumentTypeError(msg)
 
 def do_sign(args):
diff --git a/bl2/ext/mcuboot/scripts/imgtool/__init__.py b/bl2/ext/mcuboot/scripts/imgtool/__init__.py
index 107921f..fd24044 100644
--- a/bl2/ext/mcuboot/scripts/imgtool/__init__.py
+++ b/bl2/ext/mcuboot/scripts/imgtool/__init__.py
@@ -11,3 +11,8 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+# This file is intentionally empty.
+#
+# The __init__.py files are required to make Python treat the directories as
+# containing packages.
\ No newline at end of file
diff --git a/bl2/ext/mcuboot/scripts/imgtool/image.py b/bl2/ext/mcuboot/scripts/imgtool/image.py
index 79a342d..f8309b3 100644
--- a/bl2/ext/mcuboot/scripts/imgtool/image.py
+++ b/bl2/ext/mcuboot/scripts/imgtool/image.py
@@ -30,10 +30,8 @@
 
 TLV_VALUES = {
         'KEYHASH': 0x01,
-        'SHA256': 0x10,
-        'RSA2048': 0x20,
-        'ECDSA224': 0x21,
-        'ECDSA256': 0x22, }
+        'SHA256' : 0x10,
+        'RSA2048': 0x20, }
 
 TLV_INFO_SIZE = 4
 TLV_INFO_MAGIC = 0x6907
@@ -110,8 +108,6 @@
 
         tlv = TLV()
 
-        # Note that ecdsa wants to do the hashing itself, which means
-        # we get to hash it twice.
         sha = hashlib.sha256()
         sha.update(self.payload)
         digest = sha.digest()
diff --git a/bl2/ext/mcuboot/scripts/imgtool/keys.py b/bl2/ext/mcuboot/scripts/imgtool/keys.py
index ee54a0f..9728cd0 100644
--- a/bl2/ext/mcuboot/scripts/imgtool/keys.py
+++ b/bl2/ext/mcuboot/scripts/imgtool/keys.py
@@ -1,4 +1,5 @@
 # Copyright 2017 Linaro Limited
+# Copyright (c) 2017, Arm Limited.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -19,7 +20,6 @@
 from Crypto.Hash import SHA256
 from Crypto.PublicKey import RSA
 from Crypto.Signature import PKCS1_v1_5, PKCS1_PSS
-from ecdsa import SigningKey, NIST256p, util
 import hashlib
 from pyasn1.type import namedtype, univ
 from pyasn1.codec.der.encoder import encode
@@ -67,18 +67,6 @@
         print("\n};")
         print("const unsigned int rsa_pub_key_len = {};".format(len(encoded)))
 
-    def emit_rust(self):
-        print(AUTOGEN_MESSAGE)
-        print("static RSA_PUB_KEY: &'static [u8] = &[", end='')
-        encoded = self.get_public_bytes()
-        for count, b in enumerate(encoded):
-            if count % 8 == 0:
-                print("\n    ", end='')
-            else:
-                print(" ", end='')
-            print("0x{:02x},".format(b), end='')
-        print("\n];")
-
     def sig_type(self):
         """Return the type of this signature (as a string)"""
         if sign_rsa_pss:
@@ -93,7 +81,8 @@
         return "RSA2048"
 
     def sign(self, payload):
-        sha = SHA256.new(payload)
+        converted_payload = bytes(payload)
+        sha = SHA256.new(converted_payload)
         if sign_rsa_pss:
             signer = PKCS1_PSS.new(self.key)
         else:
@@ -102,72 +91,6 @@
         assert len(signature) == self.sig_len()
         return signature
 
-class ECDSA256P1():
-    def __init__(self, key):
-        """Construct an ECDSA P-256 private key"""
-        self.key = key
-
-    @staticmethod
-    def generate():
-        return ECDSA256P1(SigningKey.generate(curve=NIST256p))
-
-    def export_private(self, path):
-        with open(path, 'wb') as f:
-            f.write(self.key.to_pem())
-
-    def get_public_bytes(self):
-        vk = self.key.get_verifying_key()
-        return bytes(vk.to_der())
-
-    def emit_c(self):
-        vk = self.key.get_verifying_key()
-        print(AUTOGEN_MESSAGE)
-        print("const unsigned char ecdsa_pub_key[] = {", end='')
-        encoded = bytes(vk.to_der())
-        for count, b in enumerate(encoded):
-            if count % 8 == 0:
-                print("\n\t", end='')
-            else:
-                print(" ", end='')
-            print("0x{:02x},".format(b), end='')
-        print("\n};")
-        print("const unsigned int ecdsa_pub_key_len = {};".format(len(encoded)))
-
-    def emit_rust(self):
-        vk = self.key.get_verifying_key()
-        print(AUTOGEN_MESSAGE)
-        print("static ECDSA_PUB_KEY: &'static [u8] = &[", end='')
-        encoded = bytes(vk.to_der())
-        for count, b in enumerate(encoded):
-            if count % 8 == 0:
-                print("\n    ", end='')
-            else:
-                print(" ", end='')
-            print("0x{:02x},".format(b), end='')
-        print("\n];")
-
-    def sign(self, payload):
-        # To make this fixed length, possibly pad with zeros.
-        sig = self.key.sign(payload, hashfunc=hashlib.sha256, sigencode=util.sigencode_der)
-        sig += b'\000' * (self.sig_len() - len(sig))
-        return sig
-
-    def sig_len(self):
-        # The DER encoding depends on the high bit, and can be
-        # anywhere from 70 to 72 bytes.  Because we have to fill in
-        # the length field before computing the signature, however,
-        # we'll give the largest, and the sig checking code will allow
-        # for it to be up to two bytes larger than the actual
-        # signature.
-        return 72
-
-    def sig_type(self):
-        """Return the type of this signature (as a string)"""
-        return "ECDSA256_SHA256"
-
-    def sig_tlv(self):
-        return "ECDSA256"
-
 def load(path):
     with open(path, 'rb') as f:
         pem = f.read()
@@ -177,7 +100,4 @@
             raise Exception("Unsupported RSA bit length, only 2048 supported")
         return RSA2048(key)
     except ValueError:
-        key = SigningKey.from_pem(pem)
-        if key.curve.name != 'NIST256p':
-            raise Exception("Unsupported ECDSA curve")
-        return ECDSA256P1(key)
+        raise Exception("Unsupported RSA key file")
diff --git a/cmake/Common/CompilerArmClangCommon.cmake b/cmake/Common/CompilerArmClangCommon.cmake
index 4059bdf..bf8bc29 100644
--- a/cmake/Common/CompilerArmClangCommon.cmake
+++ b/cmake/Common/CompilerArmClangCommon.cmake
@@ -83,9 +83,9 @@
 
 function(compiler_merge_library)
 	set( _OPTIONS_ARGS )			#Option (on/off) arguments.
-    set( _ONE_VALUE_ARGS DEST)		#Single option arguments.
-    set( _MULTI_VALUE_ARGS LIBS)	#List arguments
-    cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
+	set( _ONE_VALUE_ARGS DEST)		#Single option arguments.
+	set( _MULTI_VALUE_ARGS LIBS)	#List arguments
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
 
 	#Check passed parameters
 	if(NOT _MY_PARAMS_DEST)
@@ -109,11 +109,15 @@
 	#Mark each library file as a generated external object. This is needed to
 	#avoid error because CMake has no info how these can be built.
 	SET_SOURCE_FILES_PROPERTIES(
-	  ${_MY_PARAMS_LIBS}
-	  PROPERTIES
-	  EXTERNAL_OBJECT true
-	  GENERATED true)
+		${_MY_PARAMS_LIBS}
+		PROPERTIES
+		EXTERNAL_OBJECT true
+		GENERATED true)
 
 	#Add additional input to target
 	target_sources(${_MY_PARAMS_DEST} PRIVATE ${_MY_PARAMS_LIBS})
 endfunction()
+
+function(compiler_generate_binary_output TARGET)
+	add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_ARMCCLANG_FROMELF} ARGS --bincombined --output=$<TARGET_FILE_DIR:${TARGET}>/${TARGET}.bin $<TARGET_FILE:${TARGET}>)
+endfunction()
diff --git a/cmake/Compiler/ARMClang.cmake b/cmake/Compiler/ARMClang.cmake
index 5390a98..3d494f0 100644
--- a/cmake/Compiler/ARMClang.cmake
+++ b/cmake/Compiler/ARMClang.cmake
@@ -17,6 +17,7 @@
 
 find_program(CMAKE_ARMCCLANG_LINKER armlink HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" )
 find_program(CMAKE_ARMCCLANG_AR     armar   HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" )
+find_program(CMAKE_ARMCCLANG_FROMELF fromelf HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" )
 
 set(CMAKE_LINKER "${CMAKE_ARMCCLANG_LINKER}" CACHE FILEPATH "The ARMCC linker" FORCE)
 mark_as_advanced(CMAKE_ARMCCLANG_LINKER)
diff --git a/docs/user_guides/tfm_integration_guide.md b/docs/user_guides/tfm_integration_guide.md
index e0d78ab..d5c74f9 100644
--- a/docs/user_guides/tfm_integration_guide.md
+++ b/docs/user_guides/tfm_integration_guide.md
@@ -27,6 +27,8 @@
 files being built by the build systems need to be updated manually, as the
 platform folder being used is currently hardcoded to `sse_200_mps2`.
 
+`Note: Currently SST and BL2 bootloader use different flash interface`
+
 #### target configuration files
 Inside the base root folder of the selected target, each implementation has to
 provide its own copy of `target_cfg.c/.h`. This file has target specific
diff --git a/docs/user_guides/tfm_sw_requirement.md b/docs/user_guides/tfm_sw_requirement.md
index 182fe74..2aafa38 100644
--- a/docs/user_guides/tfm_sw_requirement.md
+++ b/docs/user_guides/tfm_sw_requirement.md
@@ -16,6 +16,10 @@
 - Cmake v3.7.0
   https://cmake.org/download/
 - GNU Make v3.81
+- Python3, with the following libraries:
+  - pycrypto
+  - pyasn1
+  - sudo apt-get install python3-crypto python3-pyasn1
 
 ### Setup a shell to enable ARM Compiler v6.7.1 and cmake after installation.
 
@@ -37,7 +41,12 @@
 - Git client latest version (https://git-scm.com/download/win)
 - Cmake v3.7.0 ( https://cmake.org/download/ )
 - Cygwin ( https://www.cygwin.com/ ). Tests done with version 2.877 (64 bits)
-- GNU make should be installed by selecting appropriate package during cygwin installation.
+- GNU make should be installed by selecting appropriate package during cygwin
+  installation.
+- Python3(native Windows version), with the following libraries:
+  - pycryptodome (pip3 install --user pycryptodome)
+  - pyasn1 (pip3 install --user pyasn1)
+- Python3 pip
 
 ### Setup Cygwin to enable ARM Compiler v6.7.1 and cmake after installation.
 
diff --git a/docs/user_guides/tfm_user_guide.md b/docs/user_guides/tfm_user_guide.md
index 8a31845..26a5fd5 100644
--- a/docs/user_guides/tfm_user_guide.md
+++ b/docs/user_guides/tfm_user_guide.md
@@ -1,13 +1,13 @@
 # Trusted Firmware M user guide
-How to compile and run TF-M example application and tests for CoreLink SSE-200
-subsystem on the MPS2 board and the Fast Model(FVP).
+How to compile and run TF-M and example test application for CoreLink SSE-200
+subsystem on the MPS2 board and on the Fast Model(FVP).
 
 Follow [build instruction](./tfm_build_instruction.md) to build the binaries.
 
 ## Execute TF-M example and regression tests on MPS2 boards and FVP ##
-The TF-M example application and tests run correctly on SMM-SSE-200 for
-MPS2 (AN521) and on the Fixed Virtual Platform model FVP_MPS2_AEMv8M
-version 11.2.23.
+The BL2 bootloader and TF-M example application and tests run correctly on
+SMM-SSE-200 for MPS2 (AN521) and on the Fixed Virtual Platform model
+FVP_MPS2_AEMv8M version 11.2.23.
 
 ### To run the example code on FVP_MPS2_AEMv8M
 Using FVP_MPS2_AEMv8M provided by DS-5 v5.27.1.
@@ -16,13 +16,13 @@
 [here](https://developer.arm.com/docs/100966/latest)*
 
 #### Example application
-
+Add `tfm_s.axf` and `tfm_ns.axf` to symbol files in Debug Configuration menu.
 ```
 <DS5_PATH>/sw/models/bin/FVP_MPS2_AEMv8M  \
 --parameter fvp_mps2.platform_type=2 \
 --parameter cpu0.baseline=0 \
 --start cpu0=0x10000004 \
---parameter cpu0.INITVTOR_S=0x10000000 \
+--parameter cpu0.INITVTOR_S=0x10080200 \
 --parameter cpu0.semihosting-enable=0 \
 --parameter fvp_mps2.DISABLE_GATING=0 \
 --parameter fvp_mps2.telnetterminal0.start_telnet=1 \
@@ -33,14 +33,16 @@
 --parameter fvp_mps2.telnetterminal2.quiet=1 \
 --application cpu0=<build_dir>/app/tfm_ns.axf \
 --application cpu0=<build_dir>/app/secure_fw/tfm_s.axf
+
 ```
 #### Regression tests
+Add `tfm_s.axf` and `tfm_ns.axf` to symbol files in Debug Configuration menu.
 ```
 <DS5_PATH>/sw/models/bin/FVP_MPS2_AEMv8M \
 --parameter fvp_mps2.platform_type=2 \
 --parameter cpu0.baseline=0 \
 --start cpu0=0x10000004 \
---parameter cpu0.INITVTOR_S=0x10000000 \
+--parameter cpu0.INITVTOR_S=0x10080200 \
 --parameter cpu0.semihosting-enable=0 \
 --parameter fvp_mps2.DISABLE_GATING=0 \
 --parameter fvp_mps2.telnetterminal0.start_telnet=1 \
@@ -52,14 +54,25 @@
 --application cpu0=<build_dir>/app/tfm_ns.axf \
 --application cpu0=<build_dir>/app/secure_fw/tfm_s.axf
 ```
+#### Running example application and regression test with BL2 bootloader
+To test TF-M with bootloader, one must apply the following changes:
+* Add `mcuboot.axf` to symbol files in DS-5 in Debug Configuration menu.
+* Change the value of `cpu0.INITVTOR_S` parameter and the last two lines of the
+previous command for this:
+```
+...
+--parameter cpu0.INITVTOR_S=0x10000000 \
+...
+--application cpu0=<build_dir>/bl2/ext/mcuboot/mcuboot.axf \
+--data cpu0=<build_dir>/app/tfm_sign.bin@0x10080000
+```
 
 ### To run the example code on SSE 200 FPGA on MPS2 board
-FPGA image is available to download [here](https://developer.arm.com/products/
-system-design/development-boards/cortex-m-prototyping-systems/mps2)
+FPGA image is available to download [here](https://developer.arm.com/products/system-design/development-boards/cortex-m-prototyping-systems/mps2)
 
-To run TF-M example application and tests in the MPS2 board, it is required to
-have SMM-SSE-200 for MPS2 (AN521) image in the MPS2 board SD card.
-The image should be located in
+To run BL2 bootloader and TF-M example application and tests in the MPS2 board,
+it is required to have SMM-SSE-200 for MPS2 (AN521) image in the MPS2 board
+SD card. The image should be located in
 `<MPS2 device name>/MB/HBI0263<board revision letter>/AN521`
 
 The MPS2 board tested is HBI0263C referred also as MPS2+.
@@ -74,11 +87,11 @@
 ```
 TITLE: Versatile Express Images Configuration File
 [IMAGES]
-TOTALIMAGES: 2                   ;Number of Images (Max: 32)
+TOTALIMAGES: 2                     ;Number of Images (Max: 32)
 IMAGE0ADDRESS: 0x00000000
-IMAGE0FILE: \Software\tfm_s.axf  ; TF-M example application secure binary
-IMAGE1ADDRESS: 0x00000000
-IMAGE1FILE: \Software\tfm_ns.axf ; TF-M example application non-secure binary
+IMAGE0FILE: \Software\mcuboot.axf  ; BL2 bootloader
+IMAGE1ADDRESS: 0x10080000
+IMAGE1FILE: \Software\tfm_sign.bin ; TF-M example application binary blob
 ```
 4. Close <MPS2 device name>/MB/HBI0263C/AN521/images.txt
 5. Unmount/eject the <MPS2 device name> unit
@@ -86,9 +99,17 @@
 7. After completing the procedure you should be able to visualize on the serial
    port (baud 115200 8n1) the following messages:
 
-```
-At the moment the examples application only shows following -
 
+At the moment BL2 bootloader together with the TF-M examples application only
+shows following:
+```
+[INF] Starting bootloader
+[INF] Image 0: magic=good, copy_done=0xff, image_ok=0xff
+[INF] Scratch: magic=bad, copy_done=0x5, image_ok=0xcf
+[INF] Boot source: slot 0
+[INF] Swap type: none
+[INF] Bootloader chainload address offset: 0x80000
+[INF] Jumping to the first image slot
 [Sec Thread] Secure image initializing!
 ```
 
@@ -98,6 +119,13 @@
 port (baud 115200 8n1) the following messages:
 
 ```
+[INF] Starting bootloader
+[INF] Image 0: magic=good, copy_done=0xff, image_ok=0xff
+[INF] Scratch: magic=bad, copy_done=0x5, image_ok=0xcf
+[INF] Boot source: slot 0
+[INF] Swap type: none
+[INF] Bootloader chainload address offset: 0x80000
+[INF] Jumping to the first image slot
 [Sec Thread] Secure image initializing!
 
 #### Execute test suites for the Secure area ####
@@ -124,6 +152,116 @@
 Note: SST reliability tests may take more than 40 minutes to run on the
       MPS2.
 
+## Software upgrade and image validation with BL2 bootloader
+
+BL2 bootloader is an integrated and ported version of an external project:
+MCUBoot. You can find further information about design and operation on
+its [website](https://www.mcuboot.com/) or
+[GitHub](https://github.com/runtimeco/mcuboot) page. Its goal is to ensure that
+only authenticated software is allowed to run on the device. Bootloader is
+started when CPU is released from reset. It runs in secure state. Public key is
+built into the bootloader image. This is used when validating the digital
+signature of the TF-M payload. In case of successful authentication, bootloader
+passes execution to the secure image. Execution never returns to bootloader
+until next reset.
+
+A default RSA key pair is stored in the repository, public key is in keys.c and
+private key is in root-rsa-2048.pem. DO NOT use them in production code, they
+are exclusively for testing! Private key must be stored in a safe place outside
+of the repository. Imgtool.py can be used to generate new key pairs.
+
+The bootloader handles the secure and non-secure images as single binary blob
+which is contiguous in the device memory. At compile time these images are
+concatenated and signed with RSA-2048 digital signature. At the end of a
+successful build signed TF-M payload can be found here:
+```
+<build_dir>/app/tfm_sign.bin
+```
+
+The device memory is partitioned in the following way:
+```
+- 0x0000_0000 - 0x0007_FFFF:    BL2 bootloader
+- 0x0008_0000 - 0x000F_FFFF:    Slot 0 : Single binary blob: Secure + Non-Secure
+                                image; Primary memory partition
+  - 0x0008_0000 - 0x0008_01FF:  Common image header
+  - 0x0008_0200 - 0x0008_xxxx:  Secure image
+  - 0x0008_xxxx - 0x0010_01FF:  Padding (with 0xFF)
+  - 0x0010_0200 - 0x0010_xxxx:  Non-secure image
+  - 0x0010_xxxx - 0x0010_xxxx:  Hash value(SHA256) and RSA signature
+                                of combined image
+
+- 0x0018_0000 - 0x0027_FFFF:    Slot 1 : Secure + Non-Secure image; Secondary
+                                memory partition, structured identically to slot
+                                0
+- 0x0028_0000 - 0x0037_FFFF:    Scratch area, used during image swapping
+```
+Original image is stored in slot 0, always image in this memory partition is
+started by the bootloader. Therefore images must always be linked to slot 0
+memory address. If bootloader finds a valid image in slot 1, which is marked for
+upgrade, contains a 4 bytes magic number at the end of the partition, then
+content of slot 0 and slot 1 will be swapped, before starting the new image from
+slot 0. Magic number in slot 1 is cleared during swap operation. Bootloader has
+a revert capability, in case of faulty firmware was upgraded and resistant
+against power-cut failures. These functionalities are described detailed in the
+original project documentation.
+
+### Test software upgrade and image validation
+
+To test software upgrade functionality, two TF-M blobs are needed. Download old
+image to slot 0 and new image to slot 1. In the following example TF-M example
+application is used as old software and TF-M regression test is used as new
+software. Follow the previous instructions with small changes.
+
+#### Test software upgrade on FVP_MPS2_AEMv8M
+```
+<DS5_PATH>/sw/models/bin/FVP_MPS2_AEMv8M  \
+--parameter fvp_mps2.platform_type=2 \
+--parameter cpu0.baseline=0 \
+--start cpu0=0x10000004 \
+--parameter cpu0.INITVTOR_S=0x10000000 \
+--parameter cpu0.semihosting-enable=0 \
+--parameter fvp_mps2.DISABLE_GATING=0 \
+--parameter fvp_mps2.telnetterminal0.start_telnet=1 \
+--parameter fvp_mps2.telnetterminal1.start_telnet=0 \
+--parameter fvp_mps2.telnetterminal2.start_telnet=0 \
+--parameter fvp_mps2.telnetterminal0.quiet=0 \
+--parameter fvp_mps2.telnetterminal1.quiet=1 \
+--parameter fvp_mps2.telnetterminal2.quiet=1 \
+--application cpu0=<build_dir>/bl2/ext/mcuboot/mcuboot.axf \
+--data cpu0=<example_app_build_dir>/app/tfm_sign.bin@0x10080000 \
+--data cpu0=<regresssion_test_build_dir>/app/tfm_sign.bin@0x10180000
+```
+
+#### Test software upgrade on SSE 200 FPGA on MPS2 board
+```
+TITLE: Versatile Express Images Configuration File
+[IMAGES]
+TOTALIMAGES: 3                     ;Number of Images (Max: 32)
+IMAGE0ADDRESS: 0x00000000
+IMAGE0FILE: \Software\mcuboot.axf  ; BL2 bootloader
+IMAGE1ADDRESS: 0x10080000
+IMAGE1FILE: \Software\tfm_sig1.bin ; TF-M example application binary blob
+IMAGE2ADDRESS: 0x10180000
+IMAGE2FILE: \Software\tfm_sig2.bin ; TF-M regression test binary blob
+```
+
+The same messages will be showed as in case of regression test with one
+difference, `Swap type: none` will be replaced with `Swap type: test`:
+```
+[INF] Image 0: magic=good, copy_done=0xff, image_ok=0xff
+[INF] Scratch: magic=bad, copy_done=0x5, image_ok=0xcf
+[INF] Boot source: slot 0
+[INF] Swap type: test
+[INF] Bootloader chainload address offset: 0x80000
+[INF] Jumping to the first image slot
+[Sec Thread] Secure image initializing!
+
+#### Execute test suites for the Secure area ####
+Running Test Suite SST secure interface tests (TFM_SST_TEST_2XXX)...
+...
+```
+This indicates that software upgrade happened.
+
 --------------
 
 *Copyright (c) 2017, Arm Limited. All rights reserved.*
diff --git a/platform/ext/Mps2SSE200.cmake b/platform/ext/Mps2SSE200.cmake
index 624ff89..919a1ab 100644
--- a/platform/ext/Mps2SSE200.cmake
+++ b/platform/ext/Mps2SSE200.cmake
@@ -68,6 +68,7 @@
 	if(CMAKE_C_COMPILER_ID STREQUAL "ARMCLANG")
 		list(APPEND ALL_SRC_ASM_S "${PLATFORM_DIR}/target/sse_200_mps2/sse_200/armclang/startup_cmsdk_sse_200_s.s")
 		list(APPEND ALL_SRC_ASM_NS "${PLATFORM_DIR}/target/sse_200_mps2/sse_200/armclang/startup_cmsdk_sse_200_ns.s")
+		list(APPEND ALL_SRC_ASM_BL2 "${PLATFORM_DIR}/target/sse_200_mps2/sse_200/armclang/startup_cmsdk_sse_200_bl2.s")
 	else()
 		message(FATAL_ERROR "No startup file is available for compiler '${CMAKE_C_COMPILER_ID}'.")
 	endif()
@@ -108,3 +109,9 @@
 	LIST(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/sse_200_mps2/mps2/mps2_board/mps2_time.c")
 	embedded_include_directories(PATH "${PLATFORM_DIR}/target/sse_200_mps2/mps2/mps2_board" ABSOLUTE)
 endif()
+
+if (NOT DEFINED MPS2_SSE200_BUILD_MPS2_BOARD_FLASH)
+	message(FATAL_ERROR "Configuration variable MPS2_SSE200_BUILD_MPS2_BOARD_FLASH (true|false) is undefined!")
+elseif(MPS2_SSE200_BUILD_MPS2_BOARD_FLASH)
+	list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/sse_200_mps2/mps2/mps2_board/mps2_flash.c")
+endif()
diff --git a/platform/ext/target/common/flash.h b/platform/ext/target/common/flash.h
index 525f866..12cd9eb 100644
--- a/platform/ext/target/common/flash.h
+++ b/platform/ext/target/common/flash.h
@@ -20,87 +20,28 @@
  * @{
  */
 
-#include <zephyr/types.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <device.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#if defined(CONFIG_FLASH_PAGE_LAYOUT)
-struct flash_pages_layout {
-	size_t pages_count; /* count of pages sequence of the same size */
-	size_t pages_size;
-};
-#endif /* CONFIG_FLASH_PAGE_LAYOUT */
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "bl2_util.h"  /* struct device */
 
-typedef int (*flash_api_read)(struct device *dev, off_t offset, void *data,
-			      size_t len);
-typedef int (*flash_api_write)(struct device *dev, off_t offset,
-			       const void *data, size_t len);
-typedef int (*flash_api_erase)(struct device *dev, off_t offset, size_t size);
-typedef int (*flash_api_write_protection)(struct device *dev, bool enable);
-
-#if defined(CONFIG_FLASH_PAGE_LAYOUT)
-/**
- * @brief Retrieve a flash device's layout.
- *
- * A flash device layout is a run-length encoded description of the
- * pages on the device. (Here, "pages" means the smallest erasable
- * areas on the flash device.)
- *
- * For flash memories which have uniform page sizes, this routine
- * returns an array of length 1, which specifies the page size and
- * number of pages in the memory.
- *
- * Layouts for flash memories with nonuniform page sizes will be
- * returned as an array with multiple elements, each of which
- * describes a group of pages that all have the same size. In this
- * case, the sequence of array elements specifies the order in which
- * these groups occur on the device.
- *
- * @param dev         Flash device whose layout to retrieve.
- * @param layout      The flash layout will be returned in this argument.
- * @param layout_size The number of elements in the returned layout.
- */
-typedef void (*flash_api_pages_layout)(struct device *dev,
-				       const struct flash_pages_layout **layout,
-				       size_t *layout_size);
-#endif /* CONFIG_FLASH_PAGE_LAYOUT */
-
-struct flash_driver_api {
-	flash_api_read read;
-	flash_api_write write;
-	flash_api_erase erase;
-	flash_api_write_protection write_protection;
-#if defined(CONFIG_FLASH_PAGE_LAYOUT)
-	flash_api_pages_layout page_layout;
-#endif /* CONFIG_FLASH_PAGE_LAYOUT */
-	const size_t write_block_size;
-};
+#define off_t int32_t
 
 /**
  *  @brief  Read data from flash
- *
- *  @param  dev             : flash dev
+ *  @param  dev             : flash device
  *  @param  offset          : Offset (byte aligned) to read
  *  @param  data            : Buffer to store read data
  *  @param  len             : Number of bytes to read.
  *
  *  @return  0 on success, negative errno code on fail.
  */
-__syscall int flash_read(struct device *dev, off_t offset, void *data,
-			 size_t len);
-
-static inline int _impl_flash_read(struct device *dev, off_t offset, void *data,
-			     size_t len)
-{
-	const struct flash_driver_api *api = dev->driver_api;
-
-	return api->read(dev, offset, data, len);
-}
+int
+flash_read(struct device *dev, off_t offset, void *data, size_t len);
 
 /**
  *  @brief  Write buffer into flash memory.
@@ -115,25 +56,15 @@
  *
  *  @return  0 on success, negative errno code on fail.
  */
-__syscall int flash_write(struct device *dev, off_t offset, const void *data,
-			  size_t len);
-
-static inline int _impl_flash_write(struct device *dev, off_t offset,
-				    const void *data, size_t len)
-{
-	const struct flash_driver_api *api = dev->driver_api;
-
-	return api->write(dev, offset, data, len);
-}
+int
+flash_write(struct device *dev, off_t offset, const void *data, size_t len);
 
 /**
  *  @brief  Erase part or all of a flash memory
  *
  *  Acceptable values of erase size and offset are subject to
- *  hardware-specific multiples of page size and offset. Please check
- *  the API implemented by the underlying sub driver, for example by
- *  using flash_get_page_info_by_offs() if that is supported by your
- *  flash driver.
+ *  hardware-specific multiples of sector size and offset. Please check the
+ *  API implemented by the underlying sub driver.
  *
  *  Prior to the invocation of this API, the flash_write_protection_set needs
  *  to be called first to disable the write protection.
@@ -143,19 +74,9 @@
  *  @param  size            : size of area to be erased
  *
  *  @return  0 on success, negative errno code on fail.
- *
- *  @see flash_get_page_info_by_offs()
- *  @see flash_get_page_info_by_idx()
  */
-__syscall int flash_erase(struct device *dev, off_t offset, size_t size);
-
-static inline int _impl_flash_erase(struct device *dev, off_t offset,
-				    size_t size)
-{
-	const struct flash_driver_api *api = dev->driver_api;
-
-	return api->erase(dev, offset, size);
-}
+int
+flash_erase(struct device *dev, off_t offset, size_t size);
 
 /**
  *  @brief  Enable or disable write protection for a flash memory
@@ -163,112 +84,18 @@
  *  This API is required to be called before the invocation of write or erase
  *  API. Please note that on some flash components, the write protection is
  *  automatically turned on again by the device after the completion of each
- *  write or erase calls. Therefore, on those flash parts, write protection needs
- *  to be disabled before each invocation of the write or erase API. Please refer
- *  to the sub-driver API or the data sheet of the flash component to get details
- *  on the write protection behavior.
+ *  write or erase calls. Therefore, on those flash parts, write protection
+ *  needs to be disabled before each invocation of the write or erase API.
+ *  Please refer to the sub-driver API or the data sheet of the flash component
+ *  to get details on the write protection behavior.
  *
  *  @param  dev             : flash device
  *  @param  enable          : enable or disable flash write protection
  *
  *  @return  0 on success, negative errno code on fail.
  */
-__syscall int flash_write_protection_set(struct device *dev, bool enable);
-
-static inline int _impl_flash_write_protection_set(struct device *dev,
-						   bool enable)
-{
-	const struct flash_driver_api *api = dev->driver_api;
-
-	return api->write_protection(dev, enable);
-}
-
-struct flash_pages_info {
-	off_t start_offset; /* offset from the base of flash address */
-	size_t size;
-	u32_t index;
-};
-
-#if defined(CONFIG_FLASH_PAGE_LAYOUT)
-/**
- *  @brief  Get size and start offset of flash page at certain flash offset.
- *
- *  @param  dev flash device
- *  @param  offset Offset within the page
- *  @param  info Page Info structure to be filled
- *
- *  @return  0 on success, -EINVAL if page of the offset doesn't exist.
- */
-__syscall int flash_get_page_info_by_offs(struct device *dev, off_t offset,
-					  struct flash_pages_info *info);
-
-/**
- *  @brief  Get size and start offset of flash page of certain index.
- *
- *  @param  dev flash device
- *  @param  page_index Index of the page. Index are counted from 0.
- *  @param  info Page Info structure to be filled
- *
- *  @return  0 on success, -EINVAL  if page of the index doesn't exist.
- */
-__syscall int flash_get_page_info_by_idx(struct device *dev, u32_t page_index,
-					 struct flash_pages_info *info);
-
-/**
- *  @brief  Get number of flash pages.
- *
- *  @param  dev flash device
- *
- *  @return  Number of flash pages.
- */
-__syscall size_t flash_get_page_count(struct device *dev);
-
-/**
- * @brief Callback type for iterating over flash pages present on a device.
- *
- * The callback should return true to continue iterating, and false to halt.
- *
- * @param info Information for current page
- * @param data Private data for callback
- * @return True to continue iteration, false to halt iteration.
- * @see flash_page_foreach()
- */
-typedef bool (*flash_page_cb)(const struct flash_pages_info *info, void *data);
-
-/**
- * @brief Iterate over flash pages on a device
- *
- * This routine iterates over all flash pages on the given device,
- * ordered by increasing start offset. For each page, it invokes the
- * given callback, passing it the page's information and a private
- * data object.
- *
- * @param dev Device whose pages to iterate over
- * @param cb Callback to invoke for each flash page
- * @param data Private data for callback function
- */
-void flash_page_foreach(struct device *dev, flash_page_cb cb, void *data);
-#endif /* CONFIG_FLASH_PAGE_LAYOUT */
-
-/**
- *  @brief  Get the minimum write block size supported by the driver
- *
- *  The Write block size supported by the driver might defer from the write
- *  block size of memory used because the driver might implements write-modify
- *  algorithm.
- *
- *  @param  dev flash device
- *
- *  @return  write block size in Bytes.
- */
-__syscall size_t flash_get_write_block_size(struct device *dev);
-
-static inline size_t _impl_flash_get_write_block_size(struct device *dev)
-{
-	const struct flash_driver_api *api = dev->driver_api;
-
-	return api->write_block_size;
-}
+int
+flash_write_protection_set(struct device *dev, bool enable);
 
 #ifdef __cplusplus
 }
@@ -278,6 +105,4 @@
  * @}
  */
 
-#include <syscalls/flash.h>
-
-#endif /* _FLASH_H_ */
+#endif /* __FLASH_H__ */
diff --git a/platform/ext/target/sse_200_mps2/mps2/mps2_board/mps2_flash.c b/platform/ext/target/sse_200_mps2/mps2/mps2_board/mps2_flash.c
new file mode 100644
index 0000000..6d38f05
--- /dev/null
+++ b/platform/ext/target/sse_200_mps2/mps2/mps2_board/mps2_flash.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <flash.h>
+#include <string.h>
+#include "target.h"
+
+
+int flash_erase(struct device *dev, off_t offset, size_t size)
+{
+    uint32_t address = FLASH_BASE_ADDRESS + offset;
+
+    memset((void *)address, 0xff, size);
+    return 0;
+}
+
+int flash_read(struct device *dev, off_t offset, void *data, size_t len)
+{
+    uint32_t address = FLASH_BASE_ADDRESS + offset;
+
+    memcpy(data, (void *)address, len);
+    return 0;
+}
+
+int flash_write(struct device *dev, off_t offset, const void *data, size_t len)
+{
+   uint32_t address = FLASH_BASE_ADDRESS + offset;
+
+   memcpy((void *)address, data, len);
+   return 0;
+}
+
+int flash_write_protection_set(struct device *dev, bool enable)
+{
+    /* Do nothing */
+    return 0;
+}
diff --git a/platform/ext/target/sse_200_mps2/sse_200/armclang/sse_200_bl2.sct b/platform/ext/target/sse_200_mps2/sse_200/armclang/sse_200_bl2.sct
new file mode 100644
index 0000000..a8ce7d9
--- /dev/null
+++ b/platform/ext/target/sse_200_mps2/sse_200/armclang/sse_200_bl2.sct
@@ -0,0 +1,30 @@
+#! armclang --target=arm-arm-none-eabi -march=armv8-m.main -E -xc
+
+/*
+ * Copyright (c) 2017 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../partition/region_defs.h"
+
+LR_CODE BL2_CODE_START {
+    ER_CODE BL2_CODE_START BL2_CODE_SIZE {
+        *.o (RESET +First)
+        .ANY (+RO)
+    }
+
+    ER_DATA BL2_DATA_START BL2_DATA_SIZE {
+        .ANY (+ZI +RW)
+    }
+}
diff --git a/platform/ext/target/sse_200_mps2/sse_200/armclang/startup_cmsdk_sse_200_bl2.s b/platform/ext/target/sse_200_mps2/sse_200/armclang/startup_cmsdk_sse_200_bl2.s
new file mode 100644
index 0000000..250a02d
--- /dev/null
+++ b/platform/ext/target/sse_200_mps2/sse_200/armclang/startup_cmsdk_sse_200_bl2.s
@@ -0,0 +1,363 @@
+;/*
+; * Copyright (c) 2016 ARM Limited
+; *
+; * Licensed under the Apache License, Version 2.0 (the "License");
+; * you may not use this file except in compliance with the License.
+; * You may obtain a copy of the License at
+; *
+; *     http://www.apache.org/licenses/LICENSE-2.0
+; *
+; * Unless required by applicable law or agreed to in writing, software
+; * distributed under the License is distributed on an "AS IS" BASIS,
+; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; * See the License for the specific language governing permissions and
+; * limitations under the License.
+; */
+;
+; This file is derivative of CMSIS V5.00 startup_ARMv8MML.s
+
+;/*
+;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
+;*/
+
+
+; <h> Stack Configuration
+;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+; </h>
+
+Stack_Size      EQU     0x00001000
+MSP_STACK_SIZE  EQU     0x00000800
+
+                AREA    STACK, NOINIT, READWRITE, ALIGN=3
+                EXPORT  Stack_Mem
+Stack_Mem       SPACE   Stack_Size
+__initial_msp
+__initial_sp    EQU     __initial_msp - MSP_STACK_SIZE
+
+Heap_Size       EQU     0x00010000
+
+                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem        SPACE   Heap_Size
+__heap_limit
+
+; Vector Table Mapped to Address 0 at Reset
+
+                AREA    RESET, DATA, READONLY
+                EXPORT  __Vectors
+                EXPORT  __Vectors_End
+                EXPORT  __Vectors_Size
+
+__Vectors       DCD     __initial_msp             ; Top of Stack
+                DCD     Reset_Handler             ; Reset Handler
+                DCD     NMI_Handler               ; NMI Handler
+                DCD     HardFault_Handler         ; Hard Fault Handler
+                DCD     MemManage_Handler         ; MPU Fault Handler
+                DCD     BusFault_Handler          ; Bus Fault Handler
+                DCD     UsageFault_Handler        ; Usage Fault Handler
+                DCD     SecureFault_Handler       ; Secure Fault Handler
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     0                         ; Reserved
+                DCD     SVC_Handler               ; SVCall Handler
+                DCD     DebugMon_Handler          ; Debug Monitor Handler
+                DCD     0                         ; Reserved
+                DCD     PendSV_Handler            ; PendSV Handler
+                DCD     SysTick_Handler           ; SysTick Handler
+
+                ; Core IoT Interrupts
+                DCD     NONSEC_WATCHDOG_RESET_Handler  ; - 0 Non-Secure Watchdog Reset Handler
+                DCD     NONSEC_WATCHDOG_Handler        ; - 1 Non-Secure Watchdog Handler
+                DCD     S32K_TIMER_Handler             ; - 2 S32K Timer Handler
+                DCD     TIMER0_Handler                 ; - 3 TIMER 0 Handler
+                DCD     TIMER1_Handler                 ; - 4 TIMER 1 Handler
+                DCD     DUALTIMER_Handler              ; - 5 Dual Timer Handler
+                DCD     0                              ; Reserved - 6
+                DCD     0                              ; Reserved - 7
+                DCD     0                              ; Reserved - 8
+                DCD     MPC_Handler                    ; - 9 MPC Combined (Secure) Handler
+                DCD     PPC_Handler                    ; - 10 PPC Combined (Secure) Handler
+                DCD     0                              ; Reserved - 11
+                DCD     0                              ; Reserved - 12
+                DCD     0                              ; Reserved - 13
+                DCD     0                              ; Reserved - 14
+                DCD     0                              ; Reserved - 15
+                DCD     0                              ; Reserved - 16
+                DCD     0                              ; Reserved - 17
+                DCD     0                              ; Reserved - 18
+                DCD     0                              ; Reserved - 19
+                DCD     0                              ; Reserved - 20
+                DCD     0                              ; Reserved - 21
+                DCD     0                              ; Reserved - 22
+                DCD     0                              ; Reserved - 23
+                DCD     0                              ; Reserved - 24
+                DCD     0                              ; Reserved - 25
+                DCD     0                              ; Reserved - 26
+                DCD     0                              ; Reserved - 27
+                DCD     0                              ; Reserved - 28
+                DCD     0                              ; Reserved - 29
+                DCD     0                              ; Reserved - 30
+                DCD     0                              ; Reserved - 31
+                ; External Interrupts
+                DCD     UARTRX0_Handler           ; 32 UART 0 RX Handler
+                DCD     UARTTX0_Handler           ; 33 UART 0 TX Handler
+                DCD     UARTRX1_Handler           ; 34 UART 1 RX Handler
+                DCD     UARTTX1_Handler           ; 35 UART 1 TX Handler
+                DCD     UARTRX2_Handler           ; 36 UART 2 RX Handler
+                DCD     UARTTX2_Handler           ; 37 UART 2 TX Handler
+                DCD     UARTRX3_Handler           ; 38 UART 3 RX Handler
+                DCD     UARTTX3_Handler           ; 39 UART 3 TX Handler
+                DCD     UARTRX4_Handler           ; 40 UART 4 RX Handler
+                DCD     UARTTX4_Handler           ; 41 UART 4 TX Handler
+                DCD     UART0_Handler             ; 42 UART 0 combined Handler
+                DCD     UART1_Handler             ; 43 UART 1 combined Handler
+                DCD     UART2_Handler             ; 44 UART 0 combined Handler
+                DCD     UART3_Handler             ; 45 UART 1 combined Handler
+                DCD     UART4_Handler             ; 46 UART 0 combined Handler
+                DCD     UARTOVF_Handler           ; 47 UART 0,1,2,3,4 Overflow Handler
+                DCD     ETHERNET_Handler          ; 48 Ethernet Handler
+                DCD     I2S_Handler               ; 49 I2S Handler
+                DCD     TSC_Handler               ; 50 Touch Screen Handler
+                DCD     SPI0_Handler              ; 51 SPI 0 Handler
+                DCD     SPI1_Handler              ; 52 SPI 1 Handler
+                DCD     SPI2_Handler              ; 53 SPI 2 Handler
+                DCD     SPI3_Handler              ; 54 SPI 3 Handler
+                DCD     SPI4_Handler              ; 55 SPI 4 Handler
+                DCD     DMA0_ERROR_Handler        ; 56 DMA 0 Error Handler
+                DCD     DMA0_TC_Handler           ; 57 DMA 0 Terminal Count Handler
+                DCD     DMA0_Handler              ; 58 DMA 0 Combined Handler
+                DCD     DMA1_ERROR_Handler        ; 59 DMA 1 Error Handler
+                DCD     DMA1_TC_Handler           ; 60 DMA 1 Terminal Count Handler
+                DCD     DMA1_Handler              ; 61 DMA 1 Combined Handler
+                DCD     DMA2_ERROR_Handler        ; 62 DMA 2 Error Handler
+                DCD     DMA2_TC_Handler           ; 63 DMA 2 Terminal Count Handler
+                DCD     DMA2_Handler              ; 64 DMA 2 Combined Handler
+                DCD     DMA3_ERROR_Handler        ; 65 DMA 3 Error Handler
+                DCD     DMA3_TC_Handler           ; 66 DMA 3 Terminal Count Handler
+                DCD     DMA3_Handler              ; 67 DMA 3 Combined Handler
+                DCD     GPIO0_Handler             ; 68 GPIO 0 Comboned Handler
+                DCD     GPIO1_Handler             ; 69 GPIO 1 Comboned Handler
+                DCD     GPIO2_Handler             ; 70 GPIO 2 Comboned Handler
+                DCD     GPIO3_Handler             ; 71 GPIO 3 Comboned Handler
+                DCD     GPIO0_0_Handler           ; 72,
+                DCD     GPIO0_1_Handler           ; 73,
+                DCD     GPIO0_2_Handler           ; 74,
+                DCD     GPIO0_3_Handler           ; 75,
+                DCD     GPIO0_4_Handler           ; 76,
+                DCD     GPIO0_5_Handler           ; 77,
+                DCD     GPIO0_6_Handler           ; 78,
+                DCD     GPIO0_7_Handler           ; 79,
+                DCD     GPIO0_8_Handler           ; 80,
+                DCD     GPIO0_9_Handler           ; 81,
+                DCD     GPIO0_10_Handler          ; 82,
+                DCD     GPIO0_11_Handler          ; 83,
+                DCD     GPIO0_12_Handler          ; 84,
+                DCD     GPIO0_13_Handler          ; 85,
+                DCD     GPIO0_14_Handler          ; 86,
+                DCD     GPIO0_15_Handler          ; 87,
+                DCD     GPIO1_0_Handler           ; 88,
+                DCD     GPIO1_1_Handler           ; 89,
+                DCD     GPIO1_2_Handler           ; 90,
+                DCD     GPIO1_3_Handler           ; 91,
+                DCD     GPIO1_4_Handler           ; 92,
+                DCD     GPIO1_5_Handler           ; 93,
+                DCD     GPIO1_6_Handler           ; 94,
+                DCD     GPIO1_7_Handler           ; 95,
+__Vectors_End
+
+__Vectors_Size  EQU     __Vectors_End - __Vectors
+
+                AREA    |.text|, CODE, READONLY
+
+
+; Reset Handler
+
+Reset_Handler   PROC
+                EXPORT  Reset_Handler             [WEAK]
+                IMPORT  SystemInit
+                IMPORT  __main
+                LDR     R0, =SystemInit
+                BLX     R0
+                LDR     R0, =__main
+                BX      R0
+                ENDP
+
+
+; Dummy Exception Handlers (infinite loops which can be modified)
+
+NMI_Handler     PROC
+                EXPORT  NMI_Handler               [WEAK]
+                B       .
+                ENDP
+HardFault_Handler\
+                PROC
+                EXPORT  HardFault_Handler         [WEAK]
+                B       .
+                ENDP
+MemManage_Handler\
+                PROC
+                EXPORT  MemManage_Handler         [WEAK]
+                B       .
+                ENDP
+BusFault_Handler\
+                PROC
+                EXPORT  BusFault_Handler          [WEAK]
+                B       .
+                ENDP
+UsageFault_Handler\
+                PROC
+                EXPORT  UsageFault_Handler        [WEAK]
+                B       .
+                ENDP
+
+SecureFault_Handler\
+                PROC
+                EXPORT  SecureFault_Handler       [WEAK]
+                B       .
+                ENDP
+
+SVC_Handler     PROC
+                EXPORT  SVC_Handler               [WEAK]
+                B       .
+                ENDP
+DebugMon_Handler\
+                PROC
+                EXPORT  DebugMon_Handler          [WEAK]
+                B       .
+                ENDP
+PendSV_Handler  PROC
+                EXPORT  PendSV_Handler            [WEAK]
+                B       .
+                ENDP
+SysTick_Handler PROC
+                EXPORT  SysTick_Handler           [WEAK]
+                B       .
+                ENDP
+MPC_Handler     PROC
+                EXPORT  MPC_Handler           [WEAK]
+                B       .
+                ENDP
+PPC_Handler     PROC
+                EXPORT  PPC_Handler           [WEAK]
+                B       .
+                ENDP
+
+Default_Handler PROC
+; Core IoT Interrupts
+                EXPORT NONSEC_WATCHDOG_RESET_Handler   [WEAK] ; - 0 Non-Secure Watchdog Reset Handler
+                EXPORT NONSEC_WATCHDOG_Handler         [WEAK] ; - 1 Non-Secure Watchdog Handler
+                EXPORT S32K_TIMER_Handler              [WEAK] ; - 2 S32K Timer Handler
+                EXPORT TIMER0_Handler                  [WEAK] ; - 3 TIMER 0 Handler
+                EXPORT TIMER1_Handler                  [WEAK] ; - 4 TIMER 1 Handler
+                EXPORT DUALTIMER_Handler               [WEAK] ; - 5 Dual Timer Handler
+; External Interrupts
+                EXPORT UARTRX0_Handler             [WEAK] ; 32 UART 0 RX Handler
+                EXPORT UARTTX0_Handler             [WEAK] ; 33 UART 0 TX Handler
+
+; Core IoT Interrupts
+NONSEC_WATCHDOG_RESET_Handler  ; - 0 Non-Secure Watchdog Reset Handler
+NONSEC_WATCHDOG_Handler        ; - 1 Non-Secure Watchdog Handler
+S32K_TIMER_Handler             ; - 2 S32K Timer Handler
+TIMER0_Handler                 ; - 3 TIMER 0 Handler
+TIMER1_Handler                 ; - 4 TIMER 1 Handler
+DUALTIMER_Handler              ; - 5 Dual Timer Handler
+; External Interrupts
+UARTRX0_Handler           ; 32 UART 0 RX Handler
+UARTTX0_Handler           ; 33 UART 0 TX Handler
+UARTRX1_Handler           ; 34 UART 1 RX Handler
+UARTTX1_Handler           ; 35 UART 1 TX Handler
+UARTRX2_Handler           ; 36 UART 2 RX Handler
+UARTTX2_Handler           ; 37 UART 2 TX Handler
+UARTRX3_Handler           ; 38 UART 3 RX Handler
+UARTTX3_Handler           ; 39 UART 3 TX Handler
+UARTRX4_Handler           ; 40 UART 4 RX Handler
+UARTTX4_Handler           ; 41 UART 4 TX Handler
+UART0_Handler             ; 42 UART 0 combined Handler
+UART1_Handler             ; 43 UART 1 combined Handler
+UART2_Handler             ; 44 UART 2 combined Handler
+UART3_Handler             ; 45 UART 3 combined Handler
+UART4_Handler             ; 46 UART 4 combined Handler
+UARTOVF_Handler           ; 47 UART 0,1,2,3,4 Overflow Handler
+ETHERNET_Handler          ; 48 Ethernet Handler
+I2S_Handler               ; 49 I2S Handler
+TSC_Handler               ; 50 Touch Screen Handler
+SPI0_Handler              ; 51 SPI 0 Handler
+SPI1_Handler              ; 52 SPI 1 Handler
+SPI2_Handler              ; 53 SPI 2 Handler
+SPI3_Handler              ; 54 SPI 3 Handler
+SPI4_Handler              ; 55 SPI 4 Handler
+DMA0_ERROR_Handler        ; 56 DMA 0 Error Handler
+DMA0_TC_Handler           ; 57 DMA 0 Terminal Count Handler
+DMA0_Handler              ; 58 DMA 0 Combined Handler
+DMA1_ERROR_Handler        ; 59 DMA 1 Error Handler
+DMA1_TC_Handler           ; 60 DMA 1 Terminal Count Handler
+DMA1_Handler              ; 61 DMA 1 Combined Handler
+DMA2_ERROR_Handler        ; 62 DMA 2 Error Handler
+DMA2_TC_Handler           ; 63 DMA 2 Terminal Count Handler
+DMA2_Handler              ; 64 DMA 2 Combined Handler
+DMA3_ERROR_Handler        ; 65 DMA 3 Error Handler
+DMA3_TC_Handler           ; 66 DMA 3 Terminal Count Handler
+DMA3_Handler              ; 67 DMA 3 Combined Handler
+GPIO0_Handler             ; 68 GPIO 0 Comboned Handler
+GPIO1_Handler             ; 69 GPIO 1 Comboned Handler
+GPIO2_Handler             ; 70 GPIO 2 Comboned Handler
+GPIO3_Handler             ; 71 GPIO 3 Comboned Handler
+GPIO0_0_Handler           ; 72 GPIO 0 has 16 individual Handlers
+GPIO0_1_Handler           ; 73
+GPIO0_2_Handler           ; 74
+GPIO0_3_Handler           ; 75
+GPIO0_4_Handler           ; 76
+GPIO0_5_Handler           ; 77
+GPIO0_6_Handler           ; 78
+GPIO0_7_Handler           ; 79
+GPIO0_8_Handler           ; 80
+GPIO0_9_Handler           ; 81
+GPIO0_10_Handler          ; 82
+GPIO0_11_Handler          ; 83
+GPIO0_12_Handler          ; 84
+GPIO0_13_Handler          ; 85
+GPIO0_14_Handler          ; 86
+GPIO0_15_Handler          ; 87
+GPIO1_0_Handler           ; 88 GPIO 1 has 8 individual Handlers
+GPIO1_1_Handler           ; 89
+GPIO1_2_Handler           ; 90
+GPIO1_3_Handler           ; 91
+GPIO1_4_Handler           ; 92
+GPIO1_5_Handler           ; 93
+GPIO1_6_Handler           ; 94
+GPIO1_7_Handler           ; 95
+                B       .
+
+                ENDP
+
+
+                ALIGN
+
+
+; User Initial Stack & Heap
+
+                IF      :DEF:__MICROLIB
+
+                EXPORT  __initial_sp
+                EXPORT  __heap_base
+                EXPORT  __heap_limit
+
+                ELSE
+
+                IMPORT  __use_two_region_memory
+                EXPORT  __user_initial_stackheap
+
+__user_initial_stackheap PROC
+                LDR     R0, =  Heap_Mem
+                LDR     R1, = __initial_sp
+                LDR     R2, = (Heap_Mem +  Heap_Size)
+                LDR     R3, = Stack_Mem
+                BX      LR
+                ENDP
+
+                ALIGN
+
+                ENDIF
+
+
+                END
diff --git a/platform/ext/target/sse_200_mps2/sse_200/partition/flash_layout.h b/platform/ext/target/sse_200_mps2/sse_200/partition/flash_layout.h
new file mode 100644
index 0000000..a0cc0d0
--- /dev/null
+++ b/platform/ext/target/sse_200_mps2/sse_200/partition/flash_layout.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FLASH_LAYOUT_H__
+#define __FLASH_LAYOUT_H__
+
+/* Flash layout on MPS2 AN521 with BL2:
+ *
+ * 0x0000_0000 BL2 - MCUBoot
+ * 0x0008_0000 Flash_area_image_0:
+ *    0x0008_0000 Secure     image primary
+ *    0x0010_0000 Non-secure image primary
+ * 0x0018_0000 Flash_area_image_1:
+ *    0x0018_0000 Secure     image secondary
+ *    0x0020_0000 Non-secure image secondary
+ * 0x0028_0000 Scratch area
+ */
+#define FLASH_BASE_ADDRESS              (0x0)
+
+#define FLASH_ALIGN                     (1)
+#define FLASH_PARTITION_SIZE            (0x80000)
+#define FLASH_AREA_IMAGE_SECTOR_SIZE    (0x4000)
+
+
+#define FLASH_AREA_BL2_OFFSET           (0x0)
+#define FLASH_AREA_BL2_SIZE             (FLASH_PARTITION_SIZE)
+
+#define FLASH_AREA_IMAGE_0_OFFSET       (0x080000)
+#define FLASH_AREA_IMAGE_0_SIZE         (2 * FLASH_PARTITION_SIZE)
+
+#define FLASH_AREA_IMAGE_1_OFFSET       (0x180000)
+#define FLASH_AREA_IMAGE_1_SIZE         (2 * FLASH_PARTITION_SIZE)
+
+#define FLASH_AREA_IMAGE_SCRATCH_OFFSET (0x280000)
+#define FLASH_AREA_IMAGE_SCRATCH_SIZE   (2 * FLASH_PARTITION_SIZE)
+
+/* Offset and size definition in flash area, used by assemble.py */
+#define SECURE_IMAGE_OFFSET             0x0
+#define SECURE_IMAGE_MAX_SIZE           0x80000
+
+#define NON_SECURE_IMAGE_OFFSET         0x80000
+#define NON_SECURE_IMAGE_MAX_SIZE       0x80000
+
+#endif /* __FLASH_LAYOUT_H__ */
diff --git a/platform/ext/target/sse_200_mps2/sse_200/partition/region_defs.h b/platform/ext/target/sse_200_mps2/sse_200/partition/region_defs.h
index afbf957..d569c61 100644
--- a/platform/ext/target/sse_200_mps2/sse_200/partition/region_defs.h
+++ b/platform/ext/target/sse_200_mps2/sse_200/partition/region_defs.h
@@ -17,58 +17,60 @@
 #ifndef __REGION_DEFS_H__
 #define __REGION_DEFS_H__
 
+#include "flash_layout.h"
+
 #define TOTAL_ROM_SIZE (0x00400000) /* 4MB */
 #define TOTAL_RAM_SIZE (0x00200000) /* 2MB */
 
 /*
- * MPC granularity is 128 KB on AN505 IoT Kit MPS2 FPGA image. Alignment
+ * MPC granularity is 128 KB on AN521 Castor MPS2 FPGA image. Alignment
  * of partitions is defined in accordance with this constraint.
  */
 
-#define BL_PARTITION_SIZE (0x80000)
-
-/*Flash partitions on MPS2 AN505 with MCUboot:
+/*Flash partitions on MPS2 AN521 with BL2:
  *
- * 0x0000_0000 MCUBoot
- * 0x0008_0000 Secure image primary
- * 0x0010_0000 Non-secure image primary
- * 0x0018_0000 Secure image secondary
- * 0x0020_0000 Non-secure image secondary
+ * 0x0000_0000 BL2 - MCUBoot
+ * 0x0008_0000 Flash_area_image_0:
+ *    0x0008_0000 Secure     image primary
+ *    0x0010_0000 Non-secure image primary
+ * 0x0018_0000 Flash_area_image_1:
+ *    0x0018_0000 Secure     image secondary
+ *    0x0020_0000 Non-secure image secondary
  * 0x0028_0000 Scratch area
  *
- * Flash partitions on bare metal
- * 0x0000_0000 Secure image
+ * Flash partitions on bare metal, if BL2 not defined:
+ * 0x0000_0000 Secure     image
  * 0x0010_0000 Non-secure image
  */
 
-#ifdef MCUBOOT
-#define  S_IMAGE_PRIMARY_PARTITION_OFFSET (0x80000)
+#ifdef BL2
+#define  S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_IMAGE_0_OFFSET)
 #else
 #define  S_IMAGE_PRIMARY_PARTITION_OFFSET (0x0)
-#endif
+#endif /* BL2 */
 
 #define NS_IMAGE_PRIMARY_PARTITION_OFFSET (0x100000)
 
 /*
- * Boot partition structure if MCUboot is used:
+ * Boot partition structure if MCUBoot is used:
  * 0x0_0000 Bootloader header
  * 0x0_0200 Image area
  * 0x7_0000 Trailer
  */
-/* IMAGE_AREA_SIZE is the space available for the software binary image.
- * It is less than the PARTITION_SIZE because we reserve space
+/* IMAGE_CODE_SIZE is the space available for the software binary image.
+ * It is less than the FLASH_PARTITION_SIZE because we reserve space
  * for the image header and trailer introduced by the bootloader. */
-#ifdef MCUBOOT
-#define BL_HEADER_SIZE      (0x200)
-#define BL_TRAILER_SIZE     (0x10000)
+#ifdef BL2
+#define BL2_HEADER_SIZE      (0x200)
+#define BL2_TRAILER_SIZE     (0x10000)
 #else
-/* No header if no bootloader, but keep IMAGE_AREA_SIZE the same */
-#define BL_HEADER_SIZE      (0x0)
-#define BL_TRAILER_SIZE     (0x10200)
-#endif
+/* No header if no bootloader, but keep IMAGE_CODE_SIZE the same */
+#define BL2_HEADER_SIZE      (0x0)
+#define BL2_TRAILER_SIZE     (0x10200)
+#endif /* BL2 */
 
-#define IMAGE_AREA_SIZE \
-            (BL_PARTITION_SIZE - BL_HEADER_SIZE - BL_TRAILER_SIZE)
+#define IMAGE_CODE_SIZE \
+            (FLASH_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
 
 #define CMSE_VENEER_REGION_SIZE     (0x00000080)
 
@@ -89,9 +91,9 @@
 
 /* Secure regions */
 #define  S_IMAGE_PRIMARY_AREA_OFFSET \
-            (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL_HEADER_SIZE)
+            (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
 #define S_CODE_START    (S_ROM_ALIAS(S_IMAGE_PRIMARY_AREA_OFFSET))
-#define S_CODE_SIZE     (IMAGE_AREA_SIZE - CMSE_VENEER_REGION_SIZE)
+#define S_CODE_SIZE     (IMAGE_CODE_SIZE - CMSE_VENEER_REGION_SIZE)
 #define S_CODE_LIMIT    (S_CODE_START + S_CODE_SIZE - 1)
 
 #define S_DATA_START    (S_RAM_ALIAS(0x0))
@@ -105,27 +107,38 @@
 
 /* Non-secure regions */
 #define NS_IMAGE_PRIMARY_AREA_OFFSET \
-                        (NS_IMAGE_PRIMARY_PARTITION_OFFSET + BL_HEADER_SIZE)
+                        (NS_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
 #define NS_CODE_START   (NS_ROM_ALIAS(NS_IMAGE_PRIMARY_AREA_OFFSET))
-#define NS_CODE_SIZE    (IMAGE_AREA_SIZE)
+#define NS_CODE_SIZE    (IMAGE_CODE_SIZE)
 #define NS_CODE_LIMIT   (NS_CODE_START + NS_CODE_SIZE - 1)
 
 /* NS partition information is used for MPC configuration */
 #define NS_PARTITION_START \
             (NS_ROM_ALIAS(NS_IMAGE_PRIMARY_PARTITION_OFFSET))
 
-#ifdef MCUBOOT
+#ifdef BL2
 /* Cover: non-secure primary + secure secondary + non-secure secondary area */
 #define NS_PARTITION_LIMIT \
-            (NS_PARTITION_START + 3 * BL_PARTITION_SIZE - 1)
+            (NS_PARTITION_START + 3 * FLASH_PARTITION_SIZE - 1)
 #else
 #define NS_PARTITION_LIMIT \
-            (NS_PARTITION_START + BL_PARTITION_SIZE - 1)
-#endif /* MCUBOOT */
+            (NS_PARTITION_START + FLASH_PARTITION_SIZE - 1)
+#endif /* BL2 */
 
 #define NS_DATA_START   (NS_RAM_ALIAS(TOTAL_RAM_SIZE/2))
 #define NS_DATA_SIZE    (TOTAL_RAM_SIZE/2)
 #define NS_DATA_LIMIT   (NS_DATA_START + NS_DATA_SIZE -1)
 
+#ifdef BL2
+/* Bootloader regions */
+#define BL2_CODE_START    (S_ROM_ALIAS(FLASH_AREA_BL2_OFFSET))
+#define BL2_CODE_SIZE     (FLASH_AREA_BL2_SIZE)
+#define BL2_CODE_LIMIT    (BL2_CODE_START + BL2_CODE_SIZE - 1)
+
+#define BL2_DATA_START    (S_RAM_ALIAS(0x0))
+#define BL2_DATA_SIZE     (TOTAL_RAM_SIZE)
+#define BL2_DATA_LIMIT    (BL2_DATA_START + BL2_DATA_SIZE - 1)
+#endif /* BL2 */
+
 #endif /* __REGION_DEFS_H__ */
 
diff --git a/readme.md b/readme.md
index 7385827..2439980 100644
--- a/readme.md
+++ b/readme.md
@@ -23,10 +23,12 @@
 external projects is limited to `app` and `platform` folders.
 The original license text is included in those source files.
 
-* The platform folder currently contains drivers imported from external project
+* The `platform` folder currently contains drivers imported from external
+  project and the files have Apache 2.0 license.
+* The `app` folder contains files imported from CMSIS_5 project
   and the files have Apache 2.0 license.
-* The app folder contains files imported from CMSIS_5 project
-  and the files have Apache 2.0 license.
+* The `bl2` folder contains files imported from MCUBoot project and the files
+  have Apache 2.0 license.
 
 *Note* Any code that has license other than BSD-3-Clause is kept in
 specific sub folders named `ext` so that it can isolated if required.
@@ -43,9 +45,11 @@
 * Testcases running baremetal and with RTX to test the functionality.
 * Basic support for higher level isolation but it is `in progress with
 limited testing`.
+* BL2 bootloader for image authentication based on SHA256 and RSA-2048 digital
+  signature.
 * Build system based on cmake and armclang.
 
-### in progress
+### In progress
 
 * GCC support
 * Ongoing and incremental support for PSA features.
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index 8ce4e01..1b11430 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -44,6 +44,7 @@
 set(MPS2_SSE200_BUILD_UART_STDOUT On)
 set(MPS2_SSE200_BUILD_MPS2_BOARD_LEDS Off)
 set(MPS2_SSE200_BUILD_MPS2_BOARD_TIME On)
+set(MPS2_SSE200_BUILD_MPS2_BOARD_FLASH Off)
 include(${TFM_ROOT_DIR}/platform/ext/Mps2SSE200.cmake)
 
 embedded_target_include_directories(TARGET ${PROJECT_NAME} PATH ${TFM_ROOT_DIR} ABSOLUTE APPEND)
@@ -72,18 +73,22 @@
 	set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DCORE_TEST_SERVICES\"")
 endif()
 
-if (NOT DEFINED MCUBOOT)
-	message(FATAL_ERROR "Incomplete build configuration: MCUBOOT is undefined. ")
-elseif (MCUBOOT)
-    set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DMCUBOOT\"")
+if (NOT DEFINED BL2)
+	message(FATAL_ERROR "Incomplete build configuration: BL2 is undefined. ")
+elseif (BL2)
+	set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DBL2\"")
 endif()
 
 if(CORE_TEST)
 	embedded_set_target_compile_defines(TARGET ${PROJECT_NAME} LANGUAGE C DEFINES TFM_CORE_DEBUG CORE_TEST_SERVICES APPEND)
-	set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/unit_test")
-    set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "--predefine=\"-DCORE_TEST_SERVICES\"")
+	set(SECURE_AXF_DIR_PREFIX "${CMAKE_BINARY_DIR}/unit_test/")
+	set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${SECURE_AXF_DIR_PREFIX})
+	set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " --predefine=\"-DCORE_TEST_SERVICES\"")
 endif()
 
+#Generate binary file from axf
+compiler_generate_binary_output(${PROJECT_NAME})
+
 #Configure where we put the CMSE veneers generated by the compiler.
 if (NOT DEFINED S_VENEER_FILE)
 	set(S_VENEER_FILE "${CMAKE_CURRENT_BINARY_DIR}/s_veneers.o")
@@ -94,7 +99,7 @@
 #Set install location. Keep original value to avoid overriding command line
 #settings.
 if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
-  SET(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Default install location for secure_fw." FORCE)
+	SET(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Default install location for secure_fw." FORCE)
 endif()
 
 install(DIRECTORY ${TFM_ROOT_DIR}/interface/include/
diff --git a/secure_fw/services/secure_storage/BuildMbedtls.cmake b/secure_fw/services/secure_storage/BuildMbedtls.cmake
deleted file mode 100644
index 891ada5..0000000
--- a/secure_fw/services/secure_storage/BuildMbedtls.cmake
+++ /dev/null
@@ -1,76 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2017, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-
-#When included, this file will add a target to build the mbedtls libraries with
-#the same compilation setting as used by the file including this one.
-cmake_minimum_required(VERSION 3.7)
-
-#Define where mbedtls intermediate output files are stored.
-set (MBEDTLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/mbedtls")
-
-#Check input variables
-if(NOT DEFINED MBEDTLS_BUILD_TYPE)
-	message(FATAL_ERROR "Please set MBEDTLS_BUILD_TYPE to 'Debug' or 'Release' before including this file.")
-endif()
-
-if(NOT DEFINED MBEDTLS_SOURCE_DIR)
-	message(FATAL_ERROR "Please set MBEDTLS_SOURCE_DIR before including this file.")
-endif()
-
-if(NOT DEFINED MBEDTLS_INSTALL_DIR)
-	message(FATAL_ERROR "Please set MBEDTLS_INSTALL_DIR before including this file.")
-endif()
-
-if(NOT DEFINED MBEDTLS_C_FLAGS)
-	message(FATAL_ERROR "Please set MBEDTLS_C_FLAGS before including this file.")
-endif()
-
-string(APPEND MBEDTLS_C_FLAGS ${CMAKE_C_FLAGS})
-if (NOT TARGET mbedtls_lib AND NOT TARGET mbedtls_lib_install)
-	#Build mbedtls as external project.
-	#This ensures mbedtls is built with exactly defined settings.
-	#mbedtls will be used from is't install location
-	include(ExternalProject)
-	# Add mbed TLS files to the build.
-	set(_static_lib_command ${CMAKE_C_CREATE_STATIC_LIBRARY})
-	externalproject_add(mbedtls_lib
-		SOURCE_DIR ${MBEDTLS_SOURCE_DIR}
-		#Set mbedtls features
-		CMAKE_ARGS -DENABLE_TESTING=OFF -DENABLE_PROGRAMS=OFF
-		#Enforce our build system's settings.
-		CMAKE_ARGS -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-		#Inherit the build setting of this project
-		CMAKE_ARGS -DCMAKE_BUILD_TYPE=${MBEDTLS_BUILD_TYPE}
-		#C compiler settings
-		CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER:string=${CMAKE_C_COMPILER}
-		CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER_ID:string=${CMAKE_C_COMPILER_ID}
-		CMAKE_CACHE_ARGS -DCMAKE_C_FLAGS:string=${MBEDTLS_C_FLAGS}
-		CMAKE_CACHE_ARGS -DCMAKE_C_FLAGS_DEBUG:string=${CMAKE_C_FLAGS_DEBUG}
-		CMAKE_CACHE_ARGS -DCMAKE_C_FLAGS_RELEASE:string=${CMAKE_C_FLAGS_RELEASE}
-		CMAKE_CACHE_ARGS -DCMAKE_C_OUTPUT_EXTENSION:string=.o
-		CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER_WORKS:bool=true
-		#Archiver settings
-		CMAKE_CACHE_ARGS -DCMAKE_AR:string=${CMAKE_AR}
-		CMAKE_CACHE_ARGS -DCMAKE_C_CREATE_STATIC_LIBRARY:internal=${_static_lib_command}
-		CMAKE_CACHE_ARGS -DCMAKE_C_LINK_EXECUTABLE:string=${CMAKE_C_LINK_EXECUTABLE}
-		CMAKE_CACHE_ARGS -DCMAKE_STATIC_LIBRARY_PREFIX_C:string=${CMAKE_STATIC_LIBRARY_PREFIX_C}
-		CMAKE_CACHE_ARGS -DCMAKE_STATIC_LIBRARY_PREFIX_CXX:string=${CMAKE_STATIC_LIBRARY_PREFIX_CXX}
-		#Install location
-		CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:string=${MBEDTLS_INSTALL_DIR}
-		#Place for intermediate build files
-		BINARY_DIR ${MBEDTLS_BINARY_DIR})
-
-	#Add an install target to force installation after each mbedtls build. Without
-	#this target installation happens only when a clean mbedtls build is executed.
-	add_custom_target(mbedtls_lib_install
-		 COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/mbedtls -- install
-		 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mbedtls
-		 COMMENT "Installing mbedtls to ${MBEDTLS_INSTALL_DIR}"
-		 VERBATIM)
-	#Make install rule depend on mbedtls library build
-	add_dependencies(mbedtls_lib_install mbedtls_lib)
-endif()
diff --git a/secure_fw/services/secure_storage/CMakeLists.txt b/secure_fw/services/secure_storage/CMakeLists.txt
index 8a654f0..a874c79 100644
--- a/secure_fw/services/secure_storage/CMakeLists.txt
+++ b/secure_fw/services/secure_storage/CMakeLists.txt
@@ -25,6 +25,7 @@
 get_filename_component(MBEDTLS_SOURCE_DIR "${TFM_ROOT_DIR}/../mbedtls" ABSOLUTE)
 set (MBEDTLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/mbedtls")
 set (MBEDTLS_INSTALL_DIR ${MBEDTLS_BINARY_DIR}/mbedtls_install)
+set (MBEDTLS_TARGET_NAME "mbedtls_sst_lib")
 
 ###Get the definition of what files we need to build
 set (ENABLE_SECURE_STORAGE ON)
@@ -48,13 +49,13 @@
 #Build mbedtls as external project.
 #This ensures mbedtls is built with exactly defined settings.
 #mbedtls will be used from is't install location
-include(BuildMbedtls.cmake)
+include(${TFM_ROOT_DIR}/BuildMbedtls.cmake)
 
 # Specify what we build (for the secure storage service, build as a static library)
 add_library(tfm_storage STATIC ${ALL_SRC_ASM} ${ALL_SRC_C})
 embedded_set_target_compile_defines(TARGET tfm_storage LANGUAGE C DEFINES __ARM_FEATURE_CMSE=3 __thumb2__ TFM_LVL=${TFM_LVL})
 #Add a dependency on the mbed_tls_lib_install target.
-add_dependencies(tfm_storage mbedtls_lib_install)
+add_dependencies(tfm_storage ${MBEDTLS_TARGET_NAME}_install)
 #Ask the compiler to merge the mbedtls and the secure storage libraries.
 compiler_merge_library(DEST tfm_storage LIBS "${MBEDTLS_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX_C}mbedcrypto${CMAKE_STATIC_LIBRARY_SUFFIX_C}")