partition-tables.rst 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. Partition Tables
  2. ================
  3. :link_to_translation:`zh_CN:[中文]`
  4. Overview
  5. --------
  6. A single {IDF_TARGET_NAME}'s flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to (:ref:`default offset <CONFIG_PARTITION_TABLE_OFFSET>`) 0x8000 in the flash.
  7. Partition table length is 0xC00 bytes (maximum 95 partition table entries). An MD5 checksum, which is used for checking the integrity of the partition table, is appended after the table data.
  8. Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.
  9. The simplest way to use the partition table is to open the project configuration menu (``idf.py menuconfig``) and choose one of the simple predefined partition tables under :ref:`CONFIG_PARTITION_TABLE_TYPE`:
  10. * "Single factory app, no OTA"
  11. * "Factory app, two OTA definitions"
  12. In both cases the factory app is flashed at offset 0x10000. If you execute `idf.py partition_table` then it will print a summary of the partition table.
  13. Built-in Partition Tables
  14. -------------------------
  15. Here is the summary printed for the "Single factory app, no OTA" configuration::
  16. # ESP-IDF Partition Table
  17. # Name, Type, SubType, Offset, Size, Flags
  18. nvs, data, nvs, 0x9000, 0x6000,
  19. phy_init, data, phy, 0xf000, 0x1000,
  20. factory, app, factory, 0x10000, 1M,
  21. * At a 0x10000 (64KB) offset in the flash is the app labelled "factory". The bootloader will run this app by default.
  22. * There are also two data regions defined in the partition table for storing NVS library partition and PHY init data.
  23. Here is the summary printed for the "Factory app, two OTA definitions" configuration::
  24. # ESP-IDF Partition Table
  25. # Name, Type, SubType, Offset, Size, Flags
  26. nvs, data, nvs, 0x9000, 0x4000,
  27. otadata, data, ota, 0xd000, 0x2000,
  28. phy_init, data, phy, 0xf000, 0x1000,
  29. factory, 0, 0, 0x10000, 1M,
  30. ota_0, 0, ota_0, 0x110000, 1M,
  31. ota_1, 0, ota_1, 0x210000, 1M,
  32. * There are now three app partition definitions. The type of the factory app (at 0x10000) and the next two "OTA" apps are all set to "app", but their subtypes are different.
  33. * There is also a new "otadata" slot, which holds the data for OTA updates. The bootloader consults this data in order to know which app to execute. If "ota data" is empty, it will execute the factory app.
  34. Creating Custom Tables
  35. ----------------------
  36. If you choose "Custom partition table CSV" in menuconfig then you can also enter the name of a CSV file (in the project directory) to use for your partition table. The CSV file can describe any number of definitions for the table you need.
  37. The CSV format is the same format as printed in the summaries shown above. However, not all fields are required in the CSV. For example, here is the "input" CSV for the OTA partition table::
  38. # Name, Type, SubType, Offset, Size, Flags
  39. nvs, data, nvs, 0x9000, 0x4000
  40. otadata, data, ota, 0xd000, 0x2000
  41. phy_init, data, phy, 0xf000, 0x1000
  42. factory, app, factory, 0x10000, 1M
  43. ota_0, app, ota_0, , 1M
  44. ota_1, app, ota_1, , 1M
  45. nvs_key, data, nvs_keys, , 0x1000
  46. * Whitespace between fields is ignored, and so is any line starting with # (comments).
  47. * Each non-comment line in the CSV file is a partition definition.
  48. * The "Offset" field for each partition is empty. The gen_esp32part.py tool fills in each blank offset, starting after the partition table and making sure each partition is aligned correctly.
  49. Name field
  50. ~~~~~~~~~~
  51. Name field can be any meaningful name. It is not significant to the {IDF_TARGET_NAME}. Names longer than 16 characters will be truncated.
  52. Type field
  53. ~~~~~~~~~~
  54. Partition type field can be specified as ``app`` (0x00) or ``data`` (0x01). Or it can be a number 0-254 (or as hex 0x00-0xFE). Types 0x00-0x3F are reserved for ESP-IDF core functions.
  55. If your app needs to store data in a format not already supported by ESP-IDF, then please add a custom partition type value in the range 0x40-0xFE.
  56. See :cpp:type:`esp_partition_type_t` for the enum definitions for ``app`` and ``data`` partitions.
  57. If writing in C++ then specifying a application-defined partition type requires casting an integer to :cpp:type:`esp_partition_type_t` in order to use it with the :ref:`partition API <api-reference-partition-table>`. For example::
  58. static const esp_partition_type_t APP_PARTITION_TYPE_A = (esp_partition_type_t)0x40;
  59. The ESP-IDF bootloader ignores any partition types other than ``app`` (0x00) and ``data`` (0x01).
  60. SubType
  61. ~~~~~~~
  62. The 8-bit subtype field is specific to a given partition type. ESP-IDF currently only specifies the meaning of the subtype field for ``app`` and ``data`` partition types.
  63. See enum :cpp:type:`esp_partition_subtype_t` for the full list of subtypes defined by ESP-IDF, including the following:
  64. * When type is ``app``, the subtype field can be specified as ``factory`` (0x00), ``ota_0`` (0x10) ... ``ota_15`` (0x1F) or ``test`` (0x20).
  65. - ``factory`` (0x00) is the default app partition. The bootloader will execute the factory app unless there it sees a partition of type data/ota, in which case it reads this partition to determine which OTA image to boot.
  66. - OTA never updates the factory partition.
  67. - If you want to conserve flash usage in an OTA project, you can remove the factory partition and use ``ota_0`` instead.
  68. - ``ota_0`` (0x10) ... ``ota_15`` (0x1F) are the OTA app slots. When :doc:`OTA <../api-reference/system/ota>` is in use, the OTA data partition configures which app slot the bootloader should boot. When using OTA, an application should have at least two OTA application slots (``ota_0`` & ``ota_1``). Refer to the :doc:`OTA documentation <../api-reference/system/ota>` for more details.
  69. - ``test`` (0x20) is a reserved subtype for factory test procedures. It will be used as the fallback boot partition if no other valid app partition is found. It is also possible to configure the bootloader to read a GPIO input during each boot, and boot this partition if the GPIO is held low, see :ref:`bootloader_boot_from_test_firmware`.
  70. * When type is ``data``, the subtype field can be specified as ``ota`` (0x00), ``phy`` (0x01), ``nvs`` (0x02), nvs_keys (0x04), or a range of other component-specific subtypes (see :cpp:type:`subtype enum <esp_partition_subtype_t>`).
  71. - ``ota`` (0) is the :ref:`OTA data partition <ota_data_partition>` which stores information about the currently selected OTA app slot. This partition should be 0x2000 bytes in size. Refer to the :ref:`OTA documentation <ota_data_partition>` for more details.
  72. - ``phy`` (1) is for storing PHY initialisation data. This allows PHY to be configured per-device, instead of in firmware.
  73. - In the default configuration, the phy partition is not used and PHY initialisation data is compiled into the app itself. As such, this partition can be removed from the partition table to save space.
  74. - To load PHY data from this partition, open the project configuration menu (``idf.py menuconfig``) and enable :ref:`CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION` option. You will also need to flash your devices with phy init data as the esp-idf build system does not do this automatically.
  75. - ``nvs`` (2) is for the :doc:`Non-Volatile Storage (NVS) API <../api-reference/storage/nvs_flash>`.
  76. - NVS is used to store per-device PHY calibration data (different to initialisation data).
  77. - NVS is used to store WiFi data if the :doc:`esp_wifi_set_storage(WIFI_STORAGE_FLASH) <../api-reference/network/esp_wifi>` initialisation function is used.
  78. - The NVS API can also be used for other application data.
  79. - It is strongly recommended that you include an NVS partition of at least 0x3000 bytes in your project.
  80. - If using NVS API to store a lot of data, increase the NVS partition size from the default 0x6000 bytes.
  81. - ``nvs_keys`` (4) is for the NVS key partition. See :doc:`Non-Volatile Storage (NVS) API <../api-reference/storage/nvs_flash>` for more details.
  82. - It is used to store NVS encryption keys when `NVS Encryption` feature is enabled.
  83. - The size of this partition should be 4096 bytes (minimum partition size).
  84. - There are other predefined data subtypes for data storage supported by ESP-IDF. These include :doc:`FAT filesystem </api-reference/storage/fatfs>` (:cpp:enumerator:`ESP_PARTITION_SUBTYPE_DATA_FAT`), :doc:`SPIFFS </api-reference/storage/spiffs>` (:cpp:enumerator:`ESP_PARTITION_SUBTYPE_DATA_SPIFFS`), etc.
  85. Other subtypes of ``data`` type are reserved for future ESP-IDF uses.
  86. * If the partition type is any application-defined value (range 0x40-0xFE), then ``subtype`` field can be any value chosen by the application (range 0x00-0xFE).
  87. Note that when writing in C++, an application-defined subtype value requires casting to type :cpp:type:`esp_partition_subtype_t` in order to use it with the :ref:`partition API <api-reference-partition-table>`.
  88. Offset & Size
  89. ~~~~~~~~~~~~~
  90. Partitions with blank offsets in the CSV file will start after the previous partition, or after the partition table in the case of the first partition.
  91. Partitions of type ``app`` have to be placed at offsets aligned to 0x10000 (64K). If you leave the offset field blank, ``gen_esp32part.py`` will automatically align the partition. If you specify an unaligned offset for an app partition, the tool will return an error.
  92. Sizes and offsets can be specified as decimal numbers, hex numbers with the prefix 0x, or size multipliers K or M (1024 and 1024*1024 bytes).
  93. If you want the partitions in the partition table to work relative to any placement (:ref:`CONFIG_PARTITION_TABLE_OFFSET`) of the table itself, leave the offset field (in CSV file) for all partitions blank. Similarly, if changing the partition table offset then be aware that all blank partition offsets may change to match, and that any fixed offsets may now collide with the partition table (causing an error).
  94. Flags
  95. ~~~~~
  96. Only one flag is currently supported, ``encrypted``. If this field is set to ``encrypted``, this partition will be encrypted if :doc:`/security/flash-encryption` is enabled.
  97. (Note that ``app`` type partitions will always be encrypted, regardless of whether this flag is set or not.)
  98. Generating Binary Partition Table
  99. ---------------------------------
  100. The partition table which is flashed to the {IDF_TARGET_NAME} is in a binary format, not CSV. The tool :component_file:`partition_table/gen_esp32part.py` is used to convert between CSV and binary formats.
  101. If you configure the partition table CSV name in the project configuration (``idf.py menuconfig``) and then build the project or run ``idf.py partition_table``, this conversion is done as part of the build process.
  102. To convert CSV to Binary manually::
  103. python gen_esp32part.py input_partitions.csv binary_partitions.bin
  104. To convert binary format back to CSV manually::
  105. python gen_esp32part.py binary_partitions.bin input_partitions.csv
  106. To display the contents of a binary partition table on stdout (this is how the summaries displayed when running ``idf.py partition_table`` are generated::
  107. python gen_esp32part.py binary_partitions.bin
  108. MD5 checksum
  109. ~~~~~~~~~~~~
  110. The binary format of the partition table contains an MD5 checksum computed based on the partition table. This checksum is used for checking the integrity of the partition table during the boot.
  111. The MD5 checksum generation can be disabled by the ``--disable-md5sum`` option of ``gen_esp32part.py`` or by the :ref:`CONFIG_PARTITION_TABLE_MD5` option. This is useful for example when one uses a legacy bootloader which cannot process MD5 checksums and the boot fails with the error message ``invalid magic number 0xebeb``.
  112. Flashing the partition table
  113. ----------------------------
  114. * ``idf.py partition_table-flash``: will flash the partition table with esptool.py.
  115. * ``idf.py flash``: Will flash everything including the partition table.
  116. A manual flashing command is also printed as part of ``idf.py partition_table`` output.
  117. Note that updating the partition table doesn't erase data that may have been stored according to the old partition table. You can use ``idf.py erase_flash`` (or ``esptool.py erase_flash``) to erase the entire flash contents.
  118. Partition Tool (parttool.py)
  119. ----------------------------
  120. The component `partition_table` provides a tool :component_file:`parttool.py<partition_table/parttool.py>` for performing partition-related operations on a target device. The following operations can be performed using the tool:
  121. - reading a partition and saving the contents to a file (read_partition)
  122. - writing the contents of a file to a partition (write_partition)
  123. - erasing a partition (erase_partition)
  124. - retrieving info such as offset and size of a given partition (get_partition_info)
  125. The tool can either be imported and used from another Python script or invoked from shell script for users wanting to perform operation programmatically. This is facilitated by the tool's Python API
  126. and command-line interface, respectively.
  127. Python API
  128. ~~~~~~~~~~~
  129. Before anything else, make sure that the `parttool` module is imported.
  130. .. code-block:: python
  131. import sys
  132. import os
  133. idf_path = os.environ["IDF_PATH"] # get value of IDF_PATH from environment
  134. parttool_dir = os.path.join(idf_path, "components", "partition_table") # parttool.py lives in $IDF_PATH/components/partition_table
  135. sys.path.append(parttool_dir) # this enables Python to find parttool module
  136. from parttool import * # import all names inside parttool module
  137. The starting point for using the tool's Python API to do is create a `ParttoolTarget` object:
  138. .. code-block:: python
  139. # Create a partool.py target device connected on serial port /dev/ttyUSB1
  140. target = ParttoolTarget("/dev/ttyUSB1")
  141. The created object can now be used to perform operations on the target device:
  142. .. code-block:: python
  143. # Erase partition with name 'storage'
  144. target.erase_partition(PartitionName("storage"))
  145. # Read partition with type 'data' and subtype 'spiffs' and save to file 'spiffs.bin'
  146. target.read_partition(PartitionType("data", "spiffs"), "spiffs.bin")
  147. # Write to partition 'factory' the contents of a file named 'factory.bin'
  148. target.write_partition(PartitionName("factory"), "factory.bin")
  149. # Print the size of default boot partition
  150. storage = target.get_partition_info(PARTITION_BOOT_DEFAULT)
  151. print(storage.size)
  152. The partition to operate on is specified using `PartitionName` or `PartitionType` or PARTITION_BOOT_DEFAULT. As the name implies, these can be used to refer
  153. to partitions of a particular name, type-subtype combination, or the default boot partition.
  154. More information on the Python API is available in the docstrings for the tool.
  155. Command-line Interface
  156. ~~~~~~~~~~~~~~~~~~~~~~
  157. The command-line interface of `parttool.py` has the following structure:
  158. .. code-block:: bash
  159. parttool.py [command-args] [subcommand] [subcommand-args]
  160. - command-args - These are arguments that are needed for executing the main command (parttool.py), mostly pertaining to the target device
  161. - subcommand - This is the operation to be performed
  162. - subcommand-args - These are arguments that are specific to the chosen operation
  163. .. code-block:: bash
  164. # Erase partition with name 'storage'
  165. parttool.py --port "/dev/ttyUSB1" erase_partition --partition-name=storage
  166. # Read partition with type 'data' and subtype 'spiffs' and save to file 'spiffs.bin'
  167. parttool.py --port "/dev/ttyUSB1" read_partition --partition-type=data --partition-subtype=spiffs "spiffs.bin"
  168. # Write to partition 'factory' the contents of a file named 'factory.bin'
  169. parttool.py --port "/dev/ttyUSB1" write_partition --partition-name=factory "factory.bin"
  170. # Print the size of default boot partition
  171. parttool.py --port "/dev/ttyUSB1" get_partition_info --partition-boot-default --info size
  172. More information can be obtained by specifying `--help` as argument:
  173. .. code-block:: bash
  174. # Display possible subcommands and show main command argument descriptions
  175. parttool.py --help
  176. # Show descriptions for specific subcommand arguments
  177. parttool.py [subcommand] --help
  178. .. _secure boot: security/secure-boot-v1.rst