This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 081b04f05e iMXRT MCUboot support
081b04f05e is described below

commit 081b04f05ee3fa2a9f2476fe77bd268621908d24
Author: jturnsek <[email protected]>
AuthorDate: Fri Feb 24 07:12:28 2023 +0100

    iMXRT MCUboot support
---
 arch/arm/src/imxrt/Kconfig                         | 116 +++
 arch/arm/src/imxrt/Make.defs                       |   3 +
 arch/arm/src/imxrt/imxrt106x_flash.c               | 789 +++++++++++++++++++++
 arch/arm/src/imxrt/imxrt_flash.c                   |  35 +
 .../imxrt1064-evk/configs/mcuboot-app/defconfig    |  85 +++
 .../imxrt1064-evk/configs/mcuboot-loader/defconfig |  59 ++
 boards/arm/imxrt/imxrt1064-evk/scripts/Make.defs   |  16 +-
 .../imxrt1064-evk/scripts/flash-mcuboot-app.ld     | 119 ++++
 .../imxrt1064-evk/scripts/flash-mcuboot-loader.ld  | 139 ++++
 boards/arm/imxrt/imxrt1064-evk/src/Makefile        |  12 +
 boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h |  15 +
 .../arm/imxrt/imxrt1064-evk/src/imxrt_boot_image.c | 180 +++++
 boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c |  10 +
 boards/arm/imxrt/imxrt1064-evk/src/imxrt_progmem.c | 255 +++++++
 boards/arm/imxrt/imxrt1064-evk/src/imxrt_reset.c   |  62 ++
 15 files changed, 1891 insertions(+), 4 deletions(-)

diff --git a/arch/arm/src/imxrt/Kconfig b/arch/arm/src/imxrt/Kconfig
index 5dc6c436cb..296732fff5 100644
--- a/arch/arm/src/imxrt/Kconfig
+++ b/arch/arm/src/imxrt/Kconfig
@@ -151,6 +151,47 @@ config ARCH_FAMILY_IMXRT106x
        select ARMV7M_HAVE_DTCM
        select IMXRT_HIGHSPEED_GPIO
 
+config IMXRT_HAVE_OTA_PARTITION
+       bool
+       default n
+
+config IMXRT_PROGMEM
+       bool "Flash progmem support"
+       default n
+       select ARCH_HAVE_PROGMEM
+       ---help---
+               Add progmem support, start block and end block options are 
provided to
+               obtain an uniform flash memory mapping.
+
+menu "Application Image Configuration"
+choice
+       prompt "Application Image Format"
+       default IMXRT_APP_FORMAT_LEGACY
+       ---help---
+               Depending on the chosen 2nd stage bootloader, the application 
may
+               be required to be perform a specific startup routine. 
Furthermore,
+               the image binary must be formatted according to the definition 
from
+               the 2nd stage bootloader.
+
+config IMXRT_APP_FORMAT_LEGACY
+       bool "Legacy format"
+       ---help---
+               This is the legacy application image format.
+
+config IMXRT_APP_FORMAT_MCUBOOT
+       bool "MCUboot-bootable format"
+       select IMXRT_HAVE_OTA_PARTITION
+       depends on EXPERIMENTAL
+       ---help---
+               The MCUboot support of loading the firmware images.             
+
+comment "MCUboot support depends on CONFIG_EXPERIMENTAL"
+       depends on !EXPERIMENTAL
+
+endchoice # Application Image Format
+
+endmenu # Application Image Configuration
+
 # Peripheral support
 
 config IMXRT_USDHC
@@ -2781,4 +2822,79 @@ config IMXRT_USBDEV_REGDEBUG
 endmenu # USB device controller driver (DCD) options
 endif # IMXRT_USBDEV
 
+menu "Progmem MTD configuration"
+
+if IMXRT_PROGMEM
+
+comment "Progmem instance support"
+
+config IMXRT_PROGMEM_FLEXSPI_INSTANCE
+       int "FlexSPI instance number (0 or 1)"
+       default 1
+       ---help---
+               FlexSPI instance number. Base address 0x60000000 is used for 
instance 0
+               and 0x70000000 for instance 1. Other values are not supported.
+
+endif   #IMXRT_PROGMEM
+
+if IMXRT_HAVE_OTA_PARTITION
+
+comment "Application Image OTA Update support"
+
+config IMXRT_PROGMEM_OTA_PARTITION
+       bool "MTD driver"
+       default n
+       select BCH
+       select MTD
+       select MTD_BYTE_WRITE
+       select MTD_PARTITION
+       select MTD_PROGMEM
+       select IMXRT_PROGMEM
+       ---help---
+               Initialize an MTD driver for the Flash, which will
+               add an entry at /dev for application access from userspace.
+
+if IMXRT_PROGMEM_OTA_PARTITION
+config IMXRT_MCUBOOT_HEADER_SIZE
+       hex
+       default 0x200
+       depends on IMXRT_APP_FORMAT_MCUBOOT
+
+config IMXRT_OTA_PRIMARY_SLOT_DEVPATH
+       string "Application image primary slot device path"
+       default "/dev/ota0"
+
+config IMXRT_OTA_SECONDARY_SLOT_DEVPATH
+       string "Application image secondary slot device path"
+       default "/dev/ota1"
+
+config IMXRT_OTA_SCRATCH_DEVPATH
+       string "Scratch partition device path"
+       default "/dev/otascratch"
+
+config IMXRT_OTA_PRIMARY_SLOT_OFFSET
+       hex "MCUboot application image primary slot offset"
+       default "0x40000"
+
+config IMXRT_OTA_SECONDARY_SLOT_OFFSET
+       hex "MCUboot application image secondary slot offset"
+       default "0x200000"
+
+config IMXRT_OTA_SCRATCH_OFFSET
+       hex "MCUboot scratch partition offset"
+       default "0x3c0000"
+
+config IMXRT_OTA_SLOT_SIZE
+       hex "MCUboot application image slot size (in bytes)"
+       default "0x1c0000"
+
+config IMXRT_OTA_SCRATCH_SIZE
+       hex "MCUboot scratch partition size (in bytes)"
+       default "0x40000"
+
+endif   #IMXRT_PROGMEM_OTA_PARTITION
+endif   #IMXRT_HAVE_OTA_PARTITION
+
+endmenu # Progmem configuration
+
 endif # ARCH_CHIP_IMXRT
diff --git a/arch/arm/src/imxrt/Make.defs b/arch/arm/src/imxrt/Make.defs
index f67aa27b9c..bfbd4776ac 100644
--- a/arch/arm/src/imxrt/Make.defs
+++ b/arch/arm/src/imxrt/Make.defs
@@ -25,6 +25,9 @@ include armv7-m/Make.defs
 # Required i.MX RT files
 
 CHIP_CSRCS  = imxrt_allocateheap.c imxrt_start.c imxrt_clockconfig.c
+ifeq ($(CONFIG_IMXRT_PROGMEM),y)
+CHIP_CSRCS += imxrt_flash.c
+endif
 CHIP_CSRCS += imxrt_periphclks.c imxrt_irq.c imxrt_clrpend.c imxrt_gpio.c
 CHIP_CSRCS += imxrt_daisy.c imxrt_wdog.c imxrt_iomuxc.c imxrt_serial.c
 CHIP_CSRCS += imxrt_xbar.c imxrt_ocotp.c imxrt_lowputc.c
diff --git a/arch/arm/src/imxrt/imxrt106x_flash.c 
b/arch/arm/src/imxrt/imxrt106x_flash.c
new file mode 100644
index 0000000000..ef9b5ed615
--- /dev/null
+++ b/arch/arm/src/imxrt/imxrt106x_flash.c
@@ -0,0 +1,789 @@
+/****************************************************************************
+ * arch/arm/src/imxrt/imxrt106x_flash.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/* Provides standard flash access functions, to be used by the flash mtd
+ * driver.  The interface is defined in the include/nuttx/progmem.h
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/mutex.h>
+#include <debug.h>
+
+#include <stdbool.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "barriers.h"
+
+#include "hardware/rt106x/imxrt106x_memorymap.h"
+#include "arm_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_IMXRT_PROGMEM_FLEXSPI_INSTANCE == 0
+#define FLEXSPI_INSTANCE        (0)
+#else
+#define FLEXSPI_INSTANCE        (1)
+#endif
+
+#define FLASH_PAGE_SIZE         (256UL)
+#define FLASH_SECTOR_SIZE       (4096UL)
+#define FLASH_ERASEDVALUE       (0xffu)
+#define FLASH_ERASEDVALUE_DW    (0xffffffffu)
+#define PROGMEM_NBLOCKS         (1024UL)
+#define FLASH_NPAGES            ((4UL * 1024UL * 1024UL) / FLASH_PAGE_SIZE)
+
+#define FLEXSPI_CFG_BLK_TAG     (0x42464346UL)
+#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL)
+#define FLEXSPI_CFG_BLK_SIZE    (512)
+
+#define CMD_SDR 0x01
+#define CMD_DDR 0x21
+#define RADDR_SDR 0x02
+#define RADDR_DDR 0x22
+#define CADDR_SDR 0x03
+#define CADDR_DDR 0x23
+#define MODE1_SDR 0x04
+#define MODE1_DDR 0x24
+#define MODE2_SDR 0x05
+#define MODE2_DDR 0x25
+#define MODE4_SDR 0x06
+#define MODE4_DDR 0x26
+#define MODE8_SDR 0x07
+#define MODE8_DDR 0x27
+#define WRITE_SDR 0x08
+#define WRITE_DDR 0x28
+#define READ_SDR 0x09
+#define READ_DDR 0x29
+#define LEARN_SDR 0x0a
+#define LEARN_DDR 0x2a
+#define DATSZ_SDR 0x0b
+#define DATSZ_DDR 0x2b
+#define DUMMY_SDR 0x0c
+#define DUMMY_DDR 0x2c
+#define DUMMY_RWDS_SDR 0x0d
+#define DUMMY_RWDS_DDR 0x2d
+#define JMP_ON_CS 0x1f
+#define STOP 0
+
+#define FLEXSPI_1PAD 0
+#define FLEXSPI_2PAD 1
+#define FLEXSPI_4PAD 2
+#define FLEXSPI_8PAD 3
+
+#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
+    (FLEXSPI_LUT_OPERAND0(op0) | \
+     FLEXSPI_LUT_NUM_PADS0(pad0) | \
+     FLEXSPI_LUT_OPCODE0(cmd0) | \
+     FLEXSPI_LUT_OPERAND1(op1) | \
+     FLEXSPI_LUT_NUM_PADS1(pad1) | \
+     FLEXSPI_LUT_OPCODE1(cmd1))
+
+typedef enum
+{
+  FLEXSPI_SERIAL_CLK_NO_CHANGE = 0,
+  FLEXSPI_SERIAL_CLK_30MHz = 1,
+  FLEXSPI_SERIAL_CLK_50MHz = 2,
+  FLEXSPI_SERIAL_CLK_60MHz = 3,
+  FLEXSPI_SERIAL_CLK_75MHz = 4,
+  FLEXSPI_SERIAL_CLK_80MHz = 5,
+  FLEXSPI_SERIAL_CLK_100MHz = 6,
+  FLEXSPI_SERIAL_CLK_120MHz = 7,
+  FLEXSPI_SERIAL_CLK_133MHz = 8,
+  FLEXSPI_SERIAL_CLK_166MHz = 9,
+} flexspi_serial_clk_freq_t;
+
+enum
+{
+  FLEXSPI_CLK_SDR,
+  FLEXSPI_CLK_DDR,
+};
+
+typedef enum
+{
+  FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_INTERNALLY = 0,
+  FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_DQS_PAD = 1,
+  FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_SCK_PAD = 2,
+  FLEXSPI_READ_SAMPLE_CLK_EXTERNAL_INPUT_FROM_DQS_PAD = 3,
+} flexspi_read_sample_clk_t;
+
+enum
+{
+  FLEXSPI_MISC_OFFSET_DIFF_CLK_ENABLE = 0,
+  FLEXSPI_MISC_OFFSET_CK2_ENABLE = 1,
+  FLEXSPI_MISC_OFFSET_PARALLEL_ENABLE = 2,
+  FLEXSPI_MISC_OFFSET_WORD_ADDRESSABLE_ENABLE = 3,
+  FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4,
+  FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5,
+  FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6,
+  FLEXSPI_MISC_OFFSET_USE_VALID_TIME_FOR_ALL_FREQ = 7,
+  FLEXSPI_MISC_OFFSET_SECOND_PINMUX = 8,
+};
+
+enum
+{
+  FLEXSPI_DEVICE_TYPE_SERIAL_NOR = 1,
+  FLEXSPI_DEVICE_TYPE_SERIAL_NAND = 2,
+};
+
+enum
+{
+  SERIAL_FLASH_1PAD = 1,
+  SERIAL_FLASH_2PADS = 2,
+  SERIAL_FLASH_4PADS = 4,
+  SERIAL_FLASH_8PADS = 8,
+};
+
+typedef struct _lut_sequence
+{
+  uint8_t seq_num;
+  uint8_t seq_id;
+  uint16_t reserved;
+} flexspi_lut_seq_t;
+
+enum
+{
+  DEVICE_CONFIG_CMD_TYPE_GENERIC,
+  DEVICE_CONFIG_CMD_TYPE_QUADENABLE,
+  DEVICE_CONFIG_CMD_TYPE_SPI2XPI,
+  DEVICE_CONFIG_CMD_TYPE_XPI2SPI,
+  DEVICE_CONFIG_CMD_TYPE_SPI2NOCMD,
+  DEVICE_CONFIG_CMD_TYPE_RESET,
+};
+
+typedef struct
+{
+  uint8_t time_100ps;
+  uint8_t delay_cells;
+} flexspi_dll_time_t;
+
+typedef struct
+{
+  uint32_t tag;
+  uint32_t version;
+  uint32_t reserved0;
+  uint8_t read_sample_clk_src;
+  uint8_t data_hold_time;
+  uint8_t data_setup_time;
+  uint8_t column_address_width;
+  uint8_t device_mode_cfg_enable;
+  uint8_t device_mode_type;
+  uint16_t wait_time_cfg_commands;
+  flexspi_lut_seq_t device_mode_seq;
+  uint32_t device_mode_arg;
+  uint8_t config_cmd_enable;
+  uint8_t config_mode_type[3];
+  flexspi_lut_seq_t config_cmd_seqs[3];
+  uint32_t reserved1;
+  uint32_t config_cmd_args[3];
+  uint32_t reserved2;
+  uint32_t controller_misc_option;
+  uint8_t device_type;
+  uint8_t sflash_pad_type;
+  uint8_t serial_clk_freq;
+  uint8_t lut_custom_seq_enable;
+  uint32_t reserved3[2];
+  uint32_t sflash_a1_size;
+  uint32_t sflash_a2_size;
+  uint32_t sflash_b1_size;
+  uint32_t sflash_b2_size;
+  uint32_t cs_pad_setting_override;
+  uint32_t sclk_pad_setting_override;
+  uint32_t data_pad_setting_override;
+  uint32_t dqs_pad_setting_override;
+  uint32_t timeout_in_ms;
+  uint32_t command_interval;
+  flexspi_dll_time_t data_valid_time[2];
+  uint16_t busy_offset;
+  uint16_t busy_bit_polarity;
+  uint32_t lookup_table[64];
+  flexspi_lut_seq_t lut_custom_seq[12];
+  uint32_t reserved4[4];
+} flexspi_mem_config_t;
+
+typedef enum
+{
+  FLEXSPI_OPERATION_COMMAND,
+  FLEXSPI_OPERATION_CONFIG,
+  FLEXSPI_OPERATION_WRITE,
+  FLEXSPI_OPERATION_READ,
+  FLEXSPI_OPERATION_END = FLEXSPI_OPERATION_READ,
+} flexspi_operation_t;
+
+typedef struct
+{
+  flexspi_operation_t operation;
+  uint32_t base_address;
+  uint32_t seq_id;
+  uint32_t seq_num;
+  bool is_parallel_mode_enable;
+  uint32_t *tx_buffer;
+  uint32_t tx_size;
+  uint32_t *rx_buffer;
+  uint32_t rx_size;
+} flexspi_xfer_t;
+
+typedef enum
+{
+  FLEXSPI_CLOCK_CORE_CLOCK,
+  FLEXSPI_CLOCK_AHB_CLOCK,
+  FLEXSPI_CLOCK_SERIAL_ROOT_CLOCK,
+  FLEXSPI_CLOCK_IPG_CLOCK,
+} flexspi_clock_type_t;
+
+#define FLEXSPI_BITMASK(bit_offset) (1u << (bit_offset))
+
+enum
+{
+  STATUS_GROUP_GENERIC = 0,
+  STATUS_GROUP_FLEXSPINOR = 201,
+};
+
+typedef int32_t status_t;
+
+#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
+
+enum
+{
+  STATUS_SUCCESS         = MAKE_STATUS(STATUS_GROUP_GENERIC, 0),
+  STATUS_FAIL            = MAKE_STATUS(STATUS_GROUP_GENERIC, 1),
+  STATUS_READONLY        = MAKE_STATUS(STATUS_GROUP_GENERIC, 2),
+  STATUS_OUTOFRANGE      = MAKE_STATUS(STATUS_GROUP_GENERIC, 3),
+  STATUS_INVALIDARGUMENT = MAKE_STATUS(STATUS_GROUP_GENERIC, 4),
+  STATUS_TIMEOUT         = MAKE_STATUS(STATUS_GROUP_GENERIC, 5),
+  STATUS_NOTRANSFERINPROGRESS =
+    MAKE_STATUS(STATUS_GROUP_GENERIC, 6),
+  STATUS_BUSY = MAKE_STATUS(STATUS_GROUP_GENERIC, 7),
+  STATUS_NODATA =
+    MAKE_STATUS(STATUS_GROUP_GENERIC, 8),
+};
+
+enum _flexspi_nor_status
+{
+  STATUS_FLEXSPINOR_PROGRAMFAIL = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 0),
+  STATUS_FLEXSPINOR_ERASESECTORFAIL =
+    MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 1),
+  STATUS_FLEXSPINOR_ERASEALLFAIL = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 2),
+  STATUS_FLEXSPINOR_WAITTIMEOUT = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 3),
+  STATUS_FLEXSPINOR_NOTSUPPORTED = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 4),
+  STATUS_FLEXSPINOR_WRITEALIGNMENTERROR =
+    MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 5),
+  STATUS_FLEXSPINOR_COMMANDFAILURE =
+    MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 6),
+  STATUS_FLEXSPINOR_SFDP_NOTFOUND = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 7),
+  STATUS_FLEXSPINOR_UNSUPPORTED_SFDP_VERSION =
+    MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 8),
+  STATUS_FLEXSPINOR_FLASH_NOTFOUND = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 9),
+  STATUS_FLEXSPINOR_DTRREAD_DUMMYPROBEFAILED =
+    MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 10),
+};
+
+enum
+{
+  SERIAL_NOR_CFG_OPTION_TAG = 0x0c,
+  SERIAL_NOR_CFG_OPTION_DEVICETYPE_READSFDP_SDR = 0,
+  SERIAL_NOR_CFG_OPTION_DEVICETYPE_READSFDP_DDR = 1,
+  SERIAL_NOR_CFG_OPTION_DEVICETYPE_HYPERFLASH1V8 = 2,
+  SERIAL_NOR_CFG_OPTION_DEVICETYPE_HYPERFLASH3V0 = 3,
+  SERIAL_NOR_CFG_OPTION_DEVICETYPE_MACRONIXOCTALDDR = 4,
+  SERIAL_NOR_CFG_OPTION_DEVICETYPE_MACRONIXOCTALSDR = 5,
+  SERIAL_NOR_CFG_OPTION_DEVICETYPE_MICRONOCTALDDR = 6,
+  SERIAL_NOR_CFG_OPTION_DEVICETYPE_MICRONOCTALSDR = 7,
+  SERIAL_NOR_CFG_OPTION_DEVICETYPE_ADESTOOCTALDDR = 8,
+  SERIAL_NOR_CFG_OPTION_DEVICETYPE_ADESTOOCTALSDR = 9,
+};
+
+enum
+{
+  SERIAL_NOR_QUAD_MODE_NOTCONFIG = 0,
+  SERIAL_NOR_QUAD_MODE_STATUSREG1_BIT6 = 1,
+  SERIAL_NOR_QUAD_MODE_STATUSREG2_BIT1 = 2,
+  SERIAL_NOR_QUAD_MODE_STATUSREG2_BIT7 = 3,
+  SERIAL_NOR_QUAD_MODE_STATUSREG2_BIT1_0X31 = 4,
+};
+
+enum
+{
+  SERIAL_NOR_ENHANCE_MODE_DISABLED = 0,
+  SERIAL_NOR_ENHANCE_MODE_0_4_4_MODE = 1,
+  SERIAL_NOR_ENHANCE_MODE_0_8_8_MODE = 2,
+  SERIAL_NOR_ENHANCE_MODE_DATAORDERSWAPPED = 3,
+  SERIAL_NOR_ENHANCE_MODE_2NDPINMUX = 4,
+};
+
+typedef struct _serial_nor_config_option
+{
+  union
+  {
+    struct
+    {
+      uint32_t max_freq : 4;
+      uint32_t misc_mode : 4;
+      uint32_t quad_mode_setting : 4;
+      uint32_t cmd_pads : 4;
+      uint32_t query_pads : 4;
+      uint32_t device_type : 4;
+      uint32_t option_size : 4;
+      uint32_t tag : 4;
+    } B;
+    uint32_t U;
+  } option0;
+
+  union
+  {
+    struct
+    {
+      uint32_t dummy_cycles : 8;
+      uint32_t status_override : 8;
+      uint32_t is_pinmux_group2 : 4;
+      uint32_t reserved : 12;
+    } B;
+    uint32_t U;
+  } option1;
+} serial_nor_config_option_t;
+
+typedef struct _flexspi_nor_config
+{
+  flexspi_mem_config_t mem_config;
+  uint32_t page_size;
+  uint32_t sector_size;
+  uint8_t ipcmd_serial_clk_freq;
+  uint8_t is_uniform_block_size;
+  uint8_t is_data_order_swapped;
+  uint8_t reserved0[1];
+  uint8_t serial_nor_type;
+  uint8_t need_exit_no_cmd_mode;
+  uint8_t half_clk_for_non_read_cmd;
+  uint8_t need_restore_no_cmd_mode;
+  uint32_t block_size;
+  uint32_t reserve2[11];
+} flexspi_nor_config_t;
+
+typedef struct
+{
+  uint32_t version;
+  status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
+  status_t (*program)(uint32_t instance, flexspi_nor_config_t *config,
+                      uint32_t dst_addr, const uint32_t *src);
+  status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
+  status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config,
+                    uint32_t start, uint32_t length_in_bytes);
+  status_t (*read)(uint32_t instance, flexspi_nor_config_t *config,
+                   uint32_t *dst, uint32_t addr, uint32_t length_in_bytes);
+  void (*clear_cache)(uint32_t instance);
+  status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
+  status_t (*update_lut)(uint32_t instance, uint32_t seq_index,
+                         const uint32_t *lut_base, uint32_t seq_number);
+  status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config,
+                         serial_nor_config_option_t *option);
+} flexspi_nor_driver_interface_t;
+
+typedef struct
+{
+  const uint32_t version;
+  const char *copyright;
+  void (*run_bootloader)(void *arg);
+  const uint32_t *reserved0;
+  const flexspi_nor_driver_interface_t *flexspi_nor_driver;
+  const uint32_t *reserved1[2];
+  const void *rtwdog_driver;
+  const void *wdog_driver;
+  const uint32_t *reserved2;
+} bootloader_api_entry_t;
+
+enum
+{
+  ENTER_BOOTLOADER_TAG = 0xeb,
+  ENTER_BOOTLOADER_MODE_DEFAULT = 0,
+  ENTER_BOOTLOADER_MODE_SERIALDOWNLOADER = 1,
+
+  ENTER_BOOTLOADER_SERIALINTERFACE_AUTO = 0,
+  ENTER_BOOTLOADER_SERIALINTERFACE_USB = 1,
+  ENTER_BOOTLOADER_SERIALINTERFACE_UART = 2,
+
+  ENTER_BOOTLOADER_IMAGEINDEX_MAX = 3,
+};
+
+typedef union
+{
+  struct
+  {
+    uint32_t image_index : 4;
+    uint32_t reserved : 12;
+    uint32_t serial_boot_interface : 4;
+    uint32_t boot_mode : 4;
+    uint32_t tag : 8;
+  } B;
+  uint32_t U;
+} run_bootloader_ctx_t;
+
+#define g_bootloader_tree (*(bootloader_api_entry_t**)0x0020001c)
+
+static inline void run_bootloader(run_bootloader_ctx_t *ctx)
+{
+  g_bootloader_tree->run_bootloader(ctx);
+}
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+status_t flexspi_nor_flash_init(uint32_t instance,
+                                flexspi_nor_config_t *config)
+{
+  return g_bootloader_tree->flexspi_nor_driver->init(instance, config);
+}
+
+status_t flexspi_nor_flash_page_program(uint32_t instance,
+                                        flexspi_nor_config_t *config,
+                                        uint32_t dst_addr,
+                                        const uint32_t *src)
+{
+  return g_bootloader_tree->flexspi_nor_driver->program(instance, config,
+         dst_addr, src);
+}
+
+status_t flexspi_nor_flash_erase_all(uint32_t instance,
+                                     flexspi_nor_config_t *config)
+{
+  return g_bootloader_tree->flexspi_nor_driver->erase_all(instance, config);
+}
+
+status_t flexspi_nor_get_config(uint32_t instance,
+                                flexspi_nor_config_t *config,
+                                serial_nor_config_option_t *option)
+{
+  return g_bootloader_tree->flexspi_nor_driver->get_config(instance, config,
+         option);
+}
+
+status_t flexspi_nor_flash_erase(uint32_t instance,
+                                 flexspi_nor_config_t *config,
+                                 uint32_t start,
+                                 uint32_t length)
+{
+  return g_bootloader_tree->flexspi_nor_driver->erase(instance, config,
+         start, length);
+}
+
+status_t flexspi_nor_flash_read(uint32_t instance,
+                                flexspi_nor_config_t *config,
+                                uint32_t *dst,
+                                uint32_t start,
+                                uint32_t bytes)
+{
+  return g_bootloader_tree->flexspi_nor_driver->read(instance, config,
+         dst, start, bytes);
+}
+
+status_t flexspi_update_lut(uint32_t instance,
+                            uint32_t seq_index,
+                            const uint32_t *lut_base,
+                            uint32_t number_of_seq)
+{
+  return g_bootloader_tree->flexspi_nor_driver->update_lut(instance,
+                                                           seq_index,
+                                                           lut_base,
+                                                           number_of_seq);
+}
+
+status_t flexspi_command_xfer(uint32_t instance, flexspi_xfer_t *xfer)
+{
+  return g_bootloader_tree->flexspi_nor_driver->xfer(instance, xfer);
+}
+
+void flexspi_clear_cache(uint32_t instance)
+{
+  g_bootloader_tree->flexspi_nor_driver->clear_cache(instance);
+}
+
+struct imxrt106x_flash_priv_s
+{
+  mutex_t  lock;
+  uint32_t ifbase;
+  uint32_t base;
+  uint32_t stblock;
+  uint32_t stpage;
+};
+
+#if CONFIG_IMXRT_PROGMEM_FLEXSPI_INSTANCE == 0
+static struct imxrt106x_flash_priv_s imxrt106x_flash_priv =
+{
+  .lock    = NXMUTEX_INITIALIZER,
+  .ifbase  = IMXRT_FLEXSPIC_BASE,
+  .base    = IMXRT_FLEXCIPHER_BASE,
+  .stblock = 0,
+  .stpage  = 0,
+};
+#else
+static struct imxrt106x_flash_priv_s imxrt106x_flash_priv =
+{
+  .lock    = NXMUTEX_INITIALIZER,
+  .ifbase  = IMXRT_FLEXSPI2C_BASE,
+  .base    = IMXRT_FLEX2CIPHER_BASE,
+  .stblock = 0,
+  .stpage  = 0,
+};
+#endif
+
+static flexspi_nor_config_t flash_config;
+static serial_nor_config_option_t config_option;
+
+static int imxrt106x_israngeerased(size_t startaddress, size_t size)
+{
+  uint32_t *addr;
+  uint8_t *baddr;
+  size_t count = 0;
+  size_t bwritten = 0;
+
+  addr = (uint32_t *)startaddress;
+  while (count + 4 <= size)
+    {
+      if (getreg32(addr) != FLASH_ERASEDVALUE_DW)
+        {
+          bwritten++;
+        }
+
+      addr++;
+      count += 4;
+    }
+
+  baddr = (uint8_t *)addr;
+  while (count < size)
+    {
+      if (getreg8(baddr) != FLASH_ERASEDVALUE)
+        {
+          bwritten++;
+        }
+
+      baddr++;
+      count++;
+    }
+
+  return bwritten;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+size_t up_progmem_erasesize(size_t block)
+{
+  return FLASH_SECTOR_SIZE;
+}
+
+size_t up_progmem_pagesize(size_t page)
+{
+  return up_progmem_erasesize(page);
+}
+
+ssize_t up_progmem_getpage(size_t addr)
+{
+  struct imxrt106x_flash_priv_s *priv = &imxrt106x_flash_priv;
+
+  return  priv->stpage + ((addr - priv->base) / FLASH_SECTOR_SIZE);
+}
+
+size_t up_progmem_getaddress(size_t page)
+{
+  struct imxrt106x_flash_priv_s *priv = &imxrt106x_flash_priv;
+
+  if (page >= PROGMEM_NBLOCKS)
+    {
+      return SIZE_MAX;
+    }
+
+  return priv->base + (page - priv->stpage) * FLASH_SECTOR_SIZE;
+}
+
+size_t up_progmem_neraseblocks(void)
+{
+  return PROGMEM_NBLOCKS;
+}
+
+bool up_progmem_isuniform(void)
+{
+  return true;
+}
+
+ssize_t up_progmem_ispageerased(size_t page)
+{
+  size_t addr;
+  size_t count;
+  size_t bwritten = 0;
+
+  if (page >= PROGMEM_NBLOCKS)
+    {
+      return -EFAULT;
+    }
+
+  for (addr = up_progmem_getaddress(page), count = up_progmem_pagesize(page);
+       count; count--, addr++)
+    {
+      if (getreg8(addr) != FLASH_ERASEDVALUE)
+        {
+          bwritten++;
+        }
+    }
+
+  return bwritten;
+}
+
+ssize_t up_progmem_eraseblock(size_t block)
+{
+  struct imxrt106x_flash_priv_s *priv = &imxrt106x_flash_priv;
+  int ret;
+  status_t status;
+  size_t block_address = (block * FLASH_SECTOR_SIZE);
+
+  ret = nxmutex_lock(&priv->lock);
+  if (ret < 0)
+    {
+      return (ssize_t)ret;
+    }
+
+  config_option.option0.U = 0xc0000008;
+
+  up_irq_disable();
+  up_disable_icache();
+  up_disable_dcache();
+
+  status = flexspi_nor_get_config(FLEXSPI_INSTANCE, &flash_config,
+                                  &config_option);
+  if (status != STATUS_SUCCESS)
+    {
+      ret = -EIO;
+      goto exit_with_lock;
+    }
+
+  status = flexspi_nor_flash_init(FLEXSPI_INSTANCE, &flash_config);
+  if (status != STATUS_SUCCESS)
+    {
+      ret = -EIO;
+      goto exit_with_lock;
+    }
+
+  status = flexspi_nor_flash_erase(FLEXSPI_INSTANCE, &flash_config,
+                                   block_address, FLASH_SECTOR_SIZE);
+  if (status != STATUS_SUCCESS)
+    {
+      ret = -EIO;
+      goto exit_with_lock;
+    }
+
+  ret = 0;
+
+exit_with_lock:
+  nxmutex_unlock(&priv->lock);
+
+  /* Verify */
+
+  if (ret == 0 &&
+      imxrt106x_israngeerased(priv->base + block_address,
+                              up_progmem_erasesize(block)) == 0)
+    {
+      ret = up_progmem_erasesize(block); /* success */
+    }
+  else
+    {
+      ret = -EIO; /* failure */
+    }
+
+  up_enable_dcache();
+  up_enable_icache();
+  up_irq_enable();
+
+  return ret;
+}
+
+ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
+{
+  struct imxrt106x_flash_priv_s *priv = &imxrt106x_flash_priv;
+  size_t written = count;
+  uint32_t *ll = (uint32_t *)buf;
+  size_t faddr;
+  status_t status;
+  int ret;
+  const size_t pagesize = FLASH_PAGE_SIZE;
+  const size_t llperpage  = pagesize / sizeof(uint32_t);
+  size_t pcount = count / pagesize;
+
+  ret = nxmutex_lock(&priv->lock);
+  if (ret < 0)
+    {
+      return (ssize_t)ret;
+    }
+
+  /* Check address and count alignment */
+
+  DEBUGASSERT(!(addr % pagesize));
+  DEBUGASSERT(!(count % pagesize));
+
+  config_option.option0.U = 0xc0000008;
+
+  up_irq_disable();
+  up_disable_icache();
+
+  status = flexspi_nor_get_config(FLEXSPI_INSTANCE, &flash_config,
+                                  &config_option);
+  if (status != STATUS_SUCCESS)
+    {
+      written = -EIO;
+      goto exit_with_lock;
+    }
+
+  status = flexspi_nor_flash_init(FLEXSPI_INSTANCE, &flash_config);
+  if (status != STATUS_SUCCESS)
+    {
+      written = -EIO;
+      goto exit_with_lock;
+    }
+
+  for (ll = (uint32_t *)buf, faddr = addr - priv->base; pcount;
+       pcount -= 1, ll += llperpage, faddr += pagesize)
+    {
+      status = flexspi_nor_flash_page_program(FLEXSPI_INSTANCE,
+                                              &flash_config, faddr, ll);
+      if (status != STATUS_SUCCESS)
+        {
+          written = -EIO;
+          break;
+        }
+    }
+
+exit_with_lock:
+  nxmutex_unlock(&priv->lock);
+  up_enable_icache();
+  up_irq_enable();
+
+  return written;
+}
+
+uint8_t up_progmem_erasestate(void)
+{
+  return FLASH_ERASEDVALUE;
+}
diff --git a/arch/arm/src/imxrt/imxrt_flash.c b/arch/arm/src/imxrt/imxrt_flash.c
new file mode 100644
index 0000000000..62f769735b
--- /dev/null
+++ b/arch/arm/src/imxrt/imxrt_flash.c
@@ -0,0 +1,35 @@
+/****************************************************************************
+ * arch/arm/src/imxrt/imxrt_flash.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#if defined(CONFIG_ARCH_FAMILY_IMXRT106x)
+#  include "imxrt106x_flash.c"
+#else
+#  error "Unsupported IMXRT chip"
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
diff --git a/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-app/defconfig 
b/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-app/defconfig
new file mode 100644
index 0000000000..16078de3cd
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-app/defconfig
@@ -0,0 +1,85 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed 
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that 
includes your
+# modifications.
+#
+# CONFIG_ARCH_LEDS is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="imxrt1064-evk"
+CONFIG_ARCH_BOARD_IMXRT1064_EVK=y
+CONFIG_ARCH_CHIP="imxrt"
+CONFIG_ARCH_CHIP_IMXRT=y
+CONFIG_ARCH_CHIP_MIMXRT1064DVL6A=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARMV7M_DCACHE=y
+CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y
+CONFIG_ARMV7M_ICACHE=y
+CONFIG_ARMV7M_USEBASEPRI=y
+CONFIG_BOARDCTL_RESET=y
+CONFIG_BOARD_LOOPSPERMSEC=104926
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_ETH0_PHY_KSZ8081=y
+CONFIG_EXAMPLES_MCUBOOT_SLOT_CONFIRM=y
+CONFIG_EXAMPLES_MCUBOOT_SWAP_TEST=y
+CONFIG_EXAMPLES_MCUBOOT_UPDATE_AGENT=y
+CONFIG_EXAMPLES_MCUBOOT_UPDATE_AGENT_DL_BUFFER_SIZE=4096
+CONFIG_EXPERIMENTAL=y
+CONFIG_FAT_LCNAMES=y
+CONFIG_FS_FAT=y
+CONFIG_FS_PROCFS=y
+CONFIG_FS_PROCFS_REGISTER=y
+CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_IMXRT_APP_FORMAT_MCUBOOT=y
+CONFIG_IMXRT_ENET=y
+CONFIG_IMXRT_LPUART1=y
+CONFIG_IMXRT_PROGMEM_OTA_PARTITION=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_STACKSIZE=4096
+CONFIG_IOB_NBUFFERS=128
+CONFIG_LIBC_HOSTNAME="i.MXRT1064 EVK"
+CONFIG_LPUART1_BAUD=9600
+CONFIG_LPUART1_SERIAL_CONSOLE=y
+CONFIG_NET=y
+CONFIG_NETDB_DNSCLIENT=y
+CONFIG_NETDEV_STATISTICS=y
+CONFIG_NETINIT_NOMAC=y
+CONFIG_NETUTILS_DISCOVER=y
+CONFIG_NETUTILS_WEBCLIENT=y
+CONFIG_NET_ARP_SEND=y
+CONFIG_NET_BROADCAST=y
+CONFIG_NET_ETH_PKTSIZE=1514
+CONFIG_NET_GUARDSIZE=4
+CONFIG_NET_ICMP=y
+CONFIG_NET_ICMP_SOCKET=y
+CONFIG_NET_ICMPv6=y
+CONFIG_NET_ICMPv6_NEIGHBOR=y
+CONFIG_NET_ICMPv6_SOCKET=y
+CONFIG_NET_IPv6=y
+CONFIG_NET_STATISTICS=y
+CONFIG_NET_TCP=y
+CONFIG_NET_TCPBACKLOG=y
+CONFIG_NET_TCP_WRITE_BUFFERS=y
+CONFIG_NET_UDP=y
+CONFIG_NET_UDP_WRITE_BUFFERS=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_MOTD=y
+CONFIG_NSH_MOTD_STRING="Welcome to Nuttx from MCUboot, this is the FIRST 
firmware."
+CONFIG_NSH_READLINE=y
+CONFIG_RAM_SIZE=1048576
+CONFIG_RAM_START=0x20200000
+CONFIG_RAW_BINARY=y
+CONFIG_READLINE_CMD_HISTORY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=14
+CONFIG_START_MONTH=3
+CONFIG_SYSTEM_DHCPC_RENEW=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_SYSTEM_PING=y
diff --git a/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-loader/defconfig 
b/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-loader/defconfig
new file mode 100644
index 0000000000..ec8ca69331
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-loader/defconfig
@@ -0,0 +1,59 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed 
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that 
includes your
+# modifications.
+#
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="imxrt1064-evk"
+CONFIG_ARCH_BOARD_IMXRT1064_EVK=y
+CONFIG_ARCH_CHIP="imxrt"
+CONFIG_ARCH_CHIP_IMXRT=y
+CONFIG_ARCH_CHIP_MIMXRT1064DVL6A=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARMV7M_DCACHE=y
+CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y
+CONFIG_ARMV7M_ICACHE=y
+CONFIG_ARMV7M_USEBASEPRI=y
+CONFIG_BOARDCTL_RESET=y
+CONFIG_BOARD_LOOPSPERMSEC=104926
+CONFIG_BOOT_MCUBOOT=y
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_FAT_LCNAMES=y
+CONFIG_FS_FAT=y
+CONFIG_FS_PROCFS=y
+CONFIG_FS_PROCFS_REGISTER=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_IMXRT_APP_FORMAT_MCUBOOT=y
+CONFIG_IMXRT_LPUART1=y
+CONFIG_IMXRT_PROGMEM_OTA_PARTITION=y
+CONFIG_INIT_ENTRYPOINT="mcuboot_loader_main"
+CONFIG_INIT_STACKSIZE=4096
+CONFIG_LIBM=y
+CONFIG_LPUART1_BAUD=9600
+CONFIG_LPUART1_SERIAL_CONSOLE=y
+CONFIG_MCUBOOT_BOOTLOADER=y
+CONFIG_MCUBOOT_VERSION="414ac87cfd8d9cedeb781f812ad6f5072e6d8a39"
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LIBRARY=y
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_MOTD=y
+CONFIG_NSH_MOTD_STRING="Welcome to Nuttx MCUboot-Loader!"
+CONFIG_NSH_READLINE=y
+CONFIG_RAM_SIZE=1048576
+CONFIG_RAM_START=0x20200000
+CONFIG_RAW_BINARY=y
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=14
+CONFIG_START_MONTH=3
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_WQUEUE_NOTIFIER=y
diff --git a/boards/arm/imxrt/imxrt1064-evk/scripts/Make.defs 
b/boards/arm/imxrt/imxrt1064-evk/scripts/Make.defs
index 4a2f40105b..f6dbc5f7a0 100644
--- a/boards/arm/imxrt/imxrt1064-evk/scripts/Make.defs
+++ b/boards/arm/imxrt/imxrt1064-evk/scripts/Make.defs
@@ -22,10 +22,18 @@ include $(TOPDIR)/.config
 include $(TOPDIR)/tools/Config.mk
 include $(TOPDIR)/arch/arm/src/armv7-m/Toolchain.defs
 
-ifeq ($(CONFIG_BOOT_RUNFROMFLASH),y)
-  LDSCRIPT = flash.ld
-else ifeq ($(CONFIG_BOOT_RUNFROMISRAM),y)
-  LDSCRIPT = flash-ocram.ld
+ifeq ($(CONFIG_IMXRT_APP_FORMAT_MCUBOOT),y)
+  ifeq ($(CONFIG_MCUBOOT_BOOTLOADER),y)
+    LDSCRIPT = flash-mcuboot-loader.ld
+  else
+    LDSCRIPT = flash-mcuboot-app.ld
+  endif
+else
+  ifeq ($(CONFIG_BOOT_RUNFROMFLASH),y)
+    LDSCRIPT = flash.ld
+  else ifeq ($(CONFIG_BOOT_RUNFROMISRAM),y)
+    LDSCRIPT = flash-ocram.ld
+  endif
 endif
 
 ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
diff --git a/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-app.ld 
b/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-app.ld
new file mode 100644
index 0000000000..7b70b44a59
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-app.ld
@@ -0,0 +1,119 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/scripts/flash.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/* Specify the memory areas */
+
+MEMORY
+{
+  flash (rx)  : ORIGIN = 0x70040200, LENGTH = 1792K - 512
+  sram  (rwx) : ORIGIN = 0x20200000, LENGTH = 512M
+  itcm  (rwx) : ORIGIN = 0x00000000, LENGTH = 128K
+  dtcm  (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
+}
+
+OUTPUT_ARCH(arm)
+EXTERN(_vectors)
+
+ENTRY(_stext)
+
+SECTIONS
+{
+    .text :
+    {
+        _stext = ABSOLUTE(.);
+        *(.vectors)
+        *(.text .text.*)
+        *(.fixup)
+        *(.gnu.warning)
+        *(.rodata .rodata.*)
+        *(.gnu.linkonce.t.*)
+        *(.glue_7)
+        *(.glue_7t)
+        *(.got)
+        *(.gcc_except_table)
+        *(.gnu.linkonce.r.*)
+        _etext = ABSOLUTE(.);
+    } > flash
+
+    .init_section :
+    {
+        _sinit = ABSOLUTE(.);
+        *(.init_array .init_array.*)
+        _einit = ABSOLUTE(.);
+    } > flash
+
+    .ARM.extab :
+    {
+        *(.ARM.extab*)
+    } > flash
+
+    .ARM.exidx :
+    {
+        __exidx_start = ABSOLUTE(.);
+        *(.ARM.exidx*)
+        __exidx_end = ABSOLUTE(.);
+    } > flash
+
+    _eronly = ABSOLUTE(.);
+
+    .data :
+    {
+        _sdata = ABSOLUTE(.);
+        *(.data .data.*)
+        *(.gnu.linkonce.d.*)
+        CONSTRUCTORS
+        . = ALIGN(4);
+        _edata = ABSOLUTE(.);
+    } > sram AT > flash
+
+    .ramfunc ALIGN(4):
+    {
+        _sramfuncs = ABSOLUTE(.);
+        *(.ramfunc  .ramfunc.*)
+        _eramfuncs = ABSOLUTE(.);
+    } > sram AT > flash
+
+    _framfuncs = LOADADDR(.ramfunc);
+
+    .bss :
+    {
+        _sbss = ABSOLUTE(.);
+        *(.bss .bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = ABSOLUTE(.);
+    } > sram
+
+    /* Stabs debugging sections. */
+
+    .stab 0 : { *(.stab) }
+    .stabstr 0 : { *(.stabstr) }
+    .stab.excl 0 : { *(.stab.excl) }
+    .stab.exclstr 0 : { *(.stab.exclstr) }
+    .stab.index 0 : { *(.stab.index) }
+    .stab.indexstr 0 : { *(.stab.indexstr) }
+    .comment 0 : { *(.comment) }
+    .debug_abbrev 0 : { *(.debug_abbrev) }
+    .debug_info 0 : { *(.debug_info) }
+    .debug_line 0 : { *(.debug_line) }
+    .debug_pubnames 0 : { *(.debug_pubnames) }
+    .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-loader.ld 
b/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-loader.ld
new file mode 100644
index 0000000000..7c80d9dee7
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-loader.ld
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/scripts/flash.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/* Specify the memory areas */
+
+MEMORY
+{
+  flash (rx)  : ORIGIN = 0x70000000, LENGTH = 256K
+  sram  (rwx) : ORIGIN = 0x20200000, LENGTH = 512M
+  itcm  (rwx) : ORIGIN = 0x00000000, LENGTH = 128K
+  dtcm  (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
+}
+
+OUTPUT_ARCH(arm)
+EXTERN(_vectors)
+EXTERN(g_flash_config)
+EXTERN(g_image_vector_table)
+EXTERN(g_boot_data)
+
+ENTRY(_stext)
+
+SECTIONS
+{
+    /* Image Vector Table and Boot Data for booting from external flash */
+
+    .boot_hdr : ALIGN(4)
+    {
+        FILL(0xff)
+        __boot_hdr_start__ = ABSOLUTE(.) ;
+        KEEP(*(.boot_hdr.conf))
+        . = 0x1000 ;
+        KEEP(*(.boot_hdr.ivt))
+        . = 0x1020 ;
+        KEEP(*(.boot_hdr.boot_data))
+        . = 0x1030 ;
+        KEEP(*(.boot_hdr.dcd_data))
+        __boot_hdr_end__ = ABSOLUTE(.) ;
+        . = 0x2000 ;
+    } >flash
+
+    .text :
+    {
+        _stext = ABSOLUTE(.);
+        *(.vectors)
+        *(.text .text.*)
+        *(.fixup)
+        *(.gnu.warning)
+        *(.rodata .rodata.*)
+        *(.gnu.linkonce.t.*)
+        *(.glue_7)
+        *(.glue_7t)
+        *(.got)
+        *(.gcc_except_table)
+        *(.gnu.linkonce.r.*)
+        _etext = ABSOLUTE(.);
+    } > flash
+
+    .init_section :
+    {
+        _sinit = ABSOLUTE(.);
+        *(.init_array .init_array.*)
+        _einit = ABSOLUTE(.);
+    } > flash
+
+    .ARM.extab :
+    {
+        *(.ARM.extab*)
+    } > flash
+
+    .ARM.exidx :
+    {
+        __exidx_start = ABSOLUTE(.);
+        *(.ARM.exidx*)
+        __exidx_end = ABSOLUTE(.);
+    } > flash
+
+    _eronly = ABSOLUTE(.);
+
+    .data :
+    {
+        _sdata = ABSOLUTE(.);
+        *(.data .data.*)
+        *(.gnu.linkonce.d.*)
+        CONSTRUCTORS
+        . = ALIGN(4);
+        _edata = ABSOLUTE(.);
+    } > sram AT > flash
+
+    .ramfunc ALIGN(4):
+    {
+        _sramfuncs = ABSOLUTE(.);
+        *(.ramfunc  .ramfunc.*)
+        _eramfuncs = ABSOLUTE(.);
+    } > sram AT > flash
+
+    _framfuncs = LOADADDR(.ramfunc);
+
+    .bss :
+    {
+        _sbss = ABSOLUTE(.);
+        *(.bss .bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = ABSOLUTE(.);
+    } > sram
+
+    /* Stabs debugging sections. */
+
+    .stab 0 : { *(.stab) }
+    .stabstr 0 : { *(.stabstr) }
+    .stab.excl 0 : { *(.stab.excl) }
+    .stab.exclstr 0 : { *(.stab.exclstr) }
+    .stab.index 0 : { *(.stab.index) }
+    .stab.indexstr 0 : { *(.stab.indexstr) }
+    .comment 0 : { *(.comment) }
+    .debug_abbrev 0 : { *(.debug_abbrev) }
+    .debug_info 0 : { *(.debug_info) }
+    .debug_line 0 : { *(.debug_line) }
+    .debug_pubnames 0 : { *(.debug_pubnames) }
+    .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/Makefile 
b/boards/arm/imxrt/imxrt1064-evk/src/Makefile
index bffdbca9ea..92dc98b1c1 100644
--- a/boards/arm/imxrt/imxrt1064-evk/src/Makefile
+++ b/boards/arm/imxrt/imxrt1064-evk/src/Makefile
@@ -86,4 +86,16 @@ ifeq ($(CONFIG_IMXRT_FLEXSPI),y)
 CSRCS += imxrt_flexspi_nor.c
 endif
 
+ifeq ($(CONFIG_IMXRT_PROGMEM),y)
+CSRCS += imxrt_progmem.c
+endif
+
+ifeq ($(CONFIG_BOARDCTL_RESET),y)
+CSRCS += imxrt_reset.c
+endif
+
+ifeq ($(CONFIG_BOARDCTL_BOOT_IMAGE),y)
+CSRCS += imxrt_boot_image.c
+endif
+
 include $(TOPDIR)/boards/Board.mk
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h 
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h
index 17894c2365..3a6111264c 100644
--- a/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h
@@ -40,6 +40,14 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
+/* Configuration ************************************************************/
+
+#define HAVE_PROGMEM_CHARDEV 1
+
+#if !defined(CONFIG_IMXRT_PROGMEM) || !defined(CONFIG_MTD_PROGMEM)
+#  undef HAVE_PROGMEM_CHARDEV
+#endif
+
 /* Touchscreen definitions **************************************************/
 
 /* The IMXRT 1050/1060 have connectors for the LCD model RK043FN02H-CT.
@@ -317,5 +325,12 @@ int imxrt_usbhost_initialize(void);
 int imxrt_flexspi_nor_initialize(void);
 #endif
 
+#ifdef CONFIG_MTD
+
+#ifdef HAVE_PROGMEM_CHARDEV
+int imxrt_progmem_init(void);
+#endif  /* HAVE_PROGMEM_CHARDEV */
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_ARM_IMXRT_IMXRT1064_EVK_SRC_IMXRT1064_EVK_H */
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_boot_image.c 
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_boot_image.c
new file mode 100644
index 0000000000..ccfa93ffff
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_boot_image.c
@@ -0,0 +1,180 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/src/imxrt_boot_image.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include <sys/boardctl.h>
+#include <nuttx/irq.h>
+#include <nuttx/cache.h>
+
+#include "nvic.h"
+#include "arm_internal.h"
+#include "barriers.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure represents the first two entries on NVIC vector table */
+
+struct arm_vector_table
+{
+  uint32_t spr;   /* Stack pointer on reset */
+  uint32_t reset; /* Pointer to reset exception handler */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void cleanup_arm_nvic(void);
+static void systick_disable(void);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name:  cleanup_arm_nvic
+ *
+ * Description:
+ *   Acknowledge and disable all interrupts in NVIC
+ *
+ * Input Parameters:
+ *   None
+ *
+ *  Returned Value:
+ *    None
+ *
+ ****************************************************************************/
+
+static void cleanup_arm_nvic(void)
+{
+  int i;
+
+  /* Allow any pending interrupts to be recognized */
+
+  ARM_ISB();
+  cpsid();
+
+  /* Disable all interrupts */
+
+  for (i = 0; i < NR_IRQS; i += 32)
+    {
+      putreg32(0xffffffff, NVIC_IRQ_CLEAR(i));
+    }
+
+  /* Clear all pending interrupts */
+
+  for (i = 0; i < NR_IRQS; i += 32)
+    {
+      putreg32(0xffffffff, NVIC_IRQ_CLRPEND(i));
+    }
+}
+
+/****************************************************************************
+ * Name:  systick_disable
+ *
+ * Description:
+ *   Disable the SysTick system timer
+ *
+ * Input Parameters:
+ *   None
+ *
+ *  Returned Value:
+ *    None
+ *
+ ****************************************************************************/
+
+static void systick_disable(void)
+{
+  putreg32(0, NVIC_SYSTICK_CTRL);
+  putreg32(NVIC_SYSTICK_RELOAD_MASK, NVIC_SYSTICK_RELOAD);
+  putreg32(0, NVIC_SYSTICK_CURRENT);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_boot_image
+ *
+ * Description:
+ *   This entry point is called by bootloader to jump to application image.
+ *
+ ****************************************************************************/
+
+int board_boot_image(const char *path, uint32_t hdr_size)
+{
+  static struct arm_vector_table vt;
+  int fd;
+  ssize_t bytes;
+
+  fd = open(path, O_RDONLY | O_CLOEXEC);
+  if (fd < 0)
+    {
+      syslog(LOG_ERR, "Failed to open %s with: %d", path, fd);
+      return fd;
+    }
+
+  bytes = pread(fd, &vt, sizeof(vt), hdr_size);
+  if (bytes != sizeof(vt))
+    {
+      syslog(LOG_ERR, "Failed to read ARM vector table: %d", bytes);
+      return bytes < 0 ? bytes : -1;
+    }
+
+  systick_disable();
+
+  cleanup_arm_nvic();
+
+#ifdef CONFIG_ARMV7M_DCACHE
+  up_disable_dcache();
+#endif
+#ifdef CONFIG_ARMV7M_ICACHE
+  up_disable_icache();
+#endif
+
+#ifdef CONFIG_ARM_MPU
+  mpu_control(false, false, false);
+#endif
+
+  /* Set main and process stack pointers */
+
+  __asm__ __volatile__("\tmsr msp, %0\n" : : "r" (vt.spr));
+  setcontrol(0x00);
+  ARM_ISB();
+  ((void (*)(void))vt.reset)();
+
+  return 0;
+}
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c 
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c
index 58272f7da4..666f68fd9b 100644
--- a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c
@@ -287,6 +287,16 @@ int imxrt_bringup(void)
     }
 #endif /* CONFIG_IMXRT_FLEXSPI */
 
+#ifdef CONFIG_MTD
+#ifdef HAVE_PROGMEM_CHARDEV
+  ret = imxrt_progmem_init();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize MTD progmem: %d\n", ret);
+    }
+#endif /* HAVE_PROGMEM_CHARDEV */
+#endif /* CONFIG_MTD */
+
   UNUSED(ret);
   return OK;
 }
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_progmem.c 
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_progmem.c
new file mode 100644
index 0000000000..bd031ee979
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_progmem.c
@@ -0,0 +1,255 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/src/imxrt_progmem.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/mount.h>
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/progmem.h>
+#include <nuttx/drivers/drivers.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/mtd/mtd.h>
+#ifdef CONFIG_BCH
+#include <nuttx/drivers/drivers.h>
+#endif
+
+#include "imxrt1064-evk.h"
+
+#ifdef HAVE_PROGMEM_CHARDEV
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ARRAYSIZE(x)                (sizeof((x)) / sizeof((x)[0]))
+
+#define PARTITION_LABEL_LEN         16
+
+/* Configuration ************************************************************/
+
+/* Make sure that support for MTD partitions is enabled */
+#ifdef CONFIG_MTD
+
+#ifndef CONFIG_MTD_PARTITION
+#  error "CONFIG_MTD_PARTITION is required"
+#endif
+
+#endif
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+#if defined(CONFIG_IMXRT_PROGMEM_OTA_PARTITION)
+
+struct ota_partition_s
+{
+  uint32_t    offset;          /* Partition offset from the beginning of MTD */
+  uint32_t    size;            /* Partition size in bytes */
+  const char *devpath;         /* Partition device path */
+};
+
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#if defined(CONFIG_IMXRT_PROGMEM_OTA_PARTITION)
+static struct mtd_dev_s *progmem_alloc_mtdpart(uint32_t mtd_offset,
+    uint32_t mtd_size);
+static int init_ota_partitions(void);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct mtd_dev_s *g_progmem_mtd;
+
+#if defined(CONFIG_IMXRT_PROGMEM_OTA_PARTITION)
+static const struct ota_partition_s g_ota_partition_table[] =
+{
+  {
+    .offset  = CONFIG_IMXRT_OTA_PRIMARY_SLOT_OFFSET,
+    .size    = CONFIG_IMXRT_OTA_SLOT_SIZE,
+    .devpath = CONFIG_IMXRT_OTA_PRIMARY_SLOT_DEVPATH
+  },
+  {
+    .offset  = CONFIG_IMXRT_OTA_SECONDARY_SLOT_OFFSET,
+    .size    = CONFIG_IMXRT_OTA_SLOT_SIZE,
+    .devpath = CONFIG_IMXRT_OTA_SECONDARY_SLOT_DEVPATH
+  },
+  {
+    .offset  = CONFIG_IMXRT_OTA_SCRATCH_OFFSET,
+    .size    = CONFIG_IMXRT_OTA_SCRATCH_SIZE,
+    .devpath = CONFIG_IMXRT_OTA_SCRATCH_DEVPATH
+  }
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#if defined(CONFIG_IMXRT_PROGMEM_OTA_PARTITION)
+
+/****************************************************************************
+ * Name: progmem_alloc_mtdpart
+ *
+ * Description:
+ *   Allocate an MTD partition from FLASH.
+ *
+ * Input Parameters:
+ *   mtd_offset - MTD Partition offset from the base address in FLASH.
+ *   mtd_size   - Size for the MTD partition.
+ *
+ * Returned Value:
+ *   MTD partition data pointer on success, NULL on failure.
+ *
+ ****************************************************************************/
+
+static struct mtd_dev_s *progmem_alloc_mtdpart(uint32_t mtd_offset,
+    uint32_t mtd_size)
+{
+  uint32_t blocks;
+  ssize_t startblock;
+
+  ASSERT((mtd_offset % up_progmem_pagesize(0)) == 0);
+  ASSERT((mtd_size % up_progmem_pagesize(0)) == 0);
+
+  finfo("\tMTD offset = 0x%"PRIx32"\n", mtd_offset);
+  finfo("\tMTD size = 0x%"PRIx32"\n", mtd_size);
+
+  startblock = up_progmem_getpage(mtd_offset + up_progmem_getaddress(0));
+  if (startblock < 0)
+    {
+      return NULL;
+    }
+
+  blocks = mtd_size / up_progmem_pagesize(0);
+
+  return mtd_partition(g_progmem_mtd, startblock, blocks);
+}
+
+/****************************************************************************
+ * Name: init_ota_partitions
+ *
+ * Description:
+ *   Initialize partitions that are dedicated to firmware OTA update.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int init_ota_partitions(void)
+{
+  int i;
+  struct mtd_dev_s *mtd;
+  int ret = 0;
+  char path[PARTITION_LABEL_LEN + 1];
+
+  for (i = 0; i < ARRAYSIZE(g_ota_partition_table); ++i)
+    {
+      const struct ota_partition_s *part = &g_ota_partition_table[i];
+      mtd = progmem_alloc_mtdpart(part->offset, part->size);
+
+      strncpy(path, (char *)part->devpath, PARTITION_LABEL_LEN);
+      path[PARTITION_LABEL_LEN] = '\0';
+
+      finfo("INFO: [label]:   %s\n", path);
+      finfo("INFO: [offset]:  0x%08" PRIx32 "\n", part->offset);
+      finfo("INFO: [size]:    0x%08" PRIx32 "\n", part->size);
+
+      if (!mtd)
+        {
+          ferr("ERROR: Failed to create MTD partition\n");
+          ret = -1;
+        }
+
+      ret = register_mtddriver(path, mtd, 0777, NULL);
+      if (ret < 0)
+        {
+          ferr("ERROR: Failed to register MTD @ %s\n", path);
+          ret = -1;
+        }
+    }
+
+  return ret;
+}
+#endif /* CONFIG_IMXRT_PROGMEM_OTA_PARTITION */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: imxrt_progmem_init
+ *
+ *   Initialize Progmem partition. Read partition information, and use
+ *   these data for creating MTD.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   0 if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+int imxrt_progmem_init(void)
+{
+  int ret = 0;
+
+  g_progmem_mtd = progmem_initialize();
+  if (g_progmem_mtd == NULL)
+    {
+      ferr("ERROR: Failed to get progmem flash MTD\n");
+      ret = -EIO;
+    }
+
+#ifdef CONFIG_IMXRT_PROGMEM_OTA_PARTITION
+  ret = init_ota_partitions();
+  if (ret < 0)
+    {
+      ferr("ERROR: Failed to create OTA partition from MTD\n");
+      ret = -EIO;
+    }
+#endif
+
+  return ret;
+}
+
+#endif /* HAVE_PROGMEM_CHARDEV */
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_reset.c 
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_reset.c
new file mode 100644
index 0000000000..f05c427060
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_reset.c
@@ -0,0 +1,62 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/src/imxrt_reset.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+
+#ifdef CONFIG_BOARDCTL_RESET
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_reset
+ *
+ * Description:
+ *   Reset board.  Support for this function is required by board-level
+ *   logic if CONFIG_BOARDCTL_RESET is selected.
+ *
+ * Input Parameters:
+ *   status - Status information provided with the reset event.  This
+ *            meaning of this status information is board-specific.  If not
+ *            used by a board, the value zero may be provided in calls to
+ *            board_reset().
+ *
+ * Returned Value:
+ *   If this function returns, then it was not possible to power-off the
+ *   board due to some constraints.  The return value int this case is a
+ *   board-specific reason for the failure to shutdown.
+ *
+ ****************************************************************************/
+
+int board_reset(int status)
+{
+  up_systemreset();
+  return 0;
+}
+
+#endif /* CONFIG_BOARDCTL_RESET */

Reply via email to