Boot Linux faster!

Check our new training course

Boot Linux faster!

Check our new training course
and Creative Commons CC-BY-SA
lecture and lab materials

Bootlin logo

Elixir Cross Referencer

.. _flash_partitions:

Device Tree Flash Partitions
############################

Device tree can be used to describe a partition layout for any flash
device in the system.

Two important uses for this mechanism are:

#. To force the Zephyr image to be linked into a specific area on
   Flash.

   This is useful, for example, if the Zephyr image must be linked at
   some offset from the flash device's start, to be loaded by a
   bootloader at runtime.

#. To generate compile-time definitions for the partition layout,
   which can be shared by Zephyr subsystems and applications to
   operate on specific areas in flash.

   This is useful, for example, to create areas for storing file
   systems or other persistent state.  These defines only describe the
   boundaries of each partition. They don't, for example, initialize a
   partition's flash contents with a file system.

Partitions are generally managed using device tree overlays. Refer to
:ref:`application_dt` for details on using overlay files.

Defining Partitions
*******************

The partition layout for a flash device is described inside the
``partitions`` child node of the flash device's node in the device
tree.

You can define partitions for any flash device on the system.

Most Zephyr-supported SoCs with flash support in device tree
will define a label ``flash0``.   This label refers to the primary
on-die flash programmed to run Zephyr. To generate partitions
for this device, add the following snippet to a device tree overlay
file:

.. We can't highlight dts at time of writing:
.. https://github.com/zephyrproject-rtos/zephyr/issues/6029
.. code-block:: none

	&flash0 {
		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			/* Define your partitions here; see below */
		};
	};

To define partitions for another flash device, modify the above to
either use its label or provide a complete path to the flash device
node in the device tree.

The content of the ``partitions`` node looks like this:

.. code-block:: none

	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		partition1_label: partition@START_OFFSET_1 {
			label = "partition1_name";
			reg = <0xSTART_OFFSET_1 0xSIZE_1>;
		};

		/* ... */

		partitionN_label: partition@START_OFFSET_N {
			label = "partitionN_name";
			reg = <0xSTART_OFFSET_N 0xSIZE_N>;
		};
	};

Where:

- ``partitionX_label`` are device tree labels that can be used
  elsewhere in the device tree to refer to the partition

- ``partitionX_name`` controls how defines generated by the Zephyr
  build system for this partition will be named

- ``START_OFFSET_x`` is the start offset in hexadecimal notation of
  the partition from the beginning of the flash device

- ``SIZE_x`` is the hexadecimal size, in bytes, of the flash partition

The partitions do not have to cover the entire flash device. The
device tree compiler currently does not check if partitions overlap;
you must ensure they do not when defining them.

Example Primary Flash Partition Layout
**************************************

Here is a complete (but hypothetical) example device tree overlay
snippet illustrating these ideas. Notice how the partitions do not
overlap, but also do not cover the entire device.

.. code-block:: none

	&flash0 {
		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			code_dts_label: partition@8000 {
				label = "zephyr-code";
				reg = <0x00008000 0x34000>;
			};

			data_dts_label: partition@70000 {
				label = "application-data";
				reg = <0x00070000 0xD000>;
			};
		};
	};

Linking Zephyr Within a Partition
*********************************

To force the linker to output a Zephyr image within a given flash
partition, add this to a device tree overlay:

.. code-block:: none

	/ {
		chosen {
			zephyr,code-partition = &slot0_partition;
		};
	};

If the ``chosen`` node has no ``zephyr,code-partition`` property, the
application image link uses the entire flash device. If a
``zephyr,code-partition`` property is defined, the application link
will be restricted to that partition.

Flash Partition Macros
**********************

The Zephyr build system generates definitions for each flash device
partition. These definitions are available to any files which
include ``<zephyr.h>``.

Consider this flash partition:

.. code-block:: none

	dts_label: partition@START_OFFSET {
		label = "def-name";
		reg = <0xSTART_OFFSET 0xSIZE>;
	};

The build system will generate the following corresponding defines:

.. code-block:: c

   #define FLASH_AREA_DEF_NAME_LABEL        "def-name"
   #define FLASH_AREA_DEF_NAME_OFFSET_0     0xSTART_OFFSET
   #define FLASH_AREA_DEF_NAME_SIZE_0       0xSIZE
   #define FLASH_AREA_DEF_NAME_OFFSET       FLASH_AREA_MCUBOOT_OFFSET_0
   #define FLASH_AREA_DEF_NAME_SIZE         FLASH_AREA_MCUBOOT_SIZE_0

As you can see, the ``label`` property is capitalized when forming the
macro names. Other simple conversions to ensure it is a valid C
identifier, such as converting "-" to "_", are also performed. The
offsets and sizes are available as well.

.. _mcuboot_partitions:

MCUboot Partitions
******************

`MCUboot`_ is a secure bootloader for 32-bit microcontrollers.

Some Zephyr boards provide definitions for the flash partitions which
are required to build MCUboot itself, as well as any applications
which must be chain-loaded by MCUboot.

The device tree labels for these partitions are:

**boot_partition**
  This is the partition where the bootloader is expected to be
  placed. MCUboot's build system will attempt to link the MCUboot
  image into this partition.

**slot0_partition**
  MCUboot loads the executable application image from this
  partition. Any application bootable by MCUboot must be linked to run
  from this partition.

**slot1_partition**
  This is the partition which stores firmware upgrade images. Zephyr
  applications which receive firmware updates must ensure the upgrade
  images are placed in this partition (the Zephyr DFU subsystem can be
  used for this purpose). MCUboot checks for upgrade images in this
  partition, and can move them to ``slot0_partition`` for execution.
  The ``slot0_partition`` and ``slot1_partition`` must be the same
  size.

**scratch_partition**
  This partition is used as temporary storage while swapping the
  contents of ``slot0_partition`` and ``slot1_partition``.

.. important::

   Upgrade images are only temporarily stored in ``slot1_partition``.
   They must be linked to execute of out of ``slot0_partition``.

See the  `MCUboot documentation`_ for more details on these partitions.

.. _MCUboot: https://mcuboot.com/

.. _MCUboot documentation:
   https://github.com/runtimeco/mcuboot/blob/master/docs/design.md#image-slots

File System Partitions
**********************

**storage_partition**
  This is the area where e.g. NFFS expects its partition.