]> granicus.if.org Git - esp-idf/commitdiff
partition_table: Hard error if CSV contains invalid/overlapping offsets
authorAngus Gratton <angus@espressif.com>
Thu, 12 Jul 2018 01:32:58 +0000 (11:32 +1000)
committerAngus Gratton <gus@projectgus.com>
Wed, 1 Aug 2018 09:23:38 +0000 (19:23 +1000)
Based on report on forum here:
https://esp32.com/viewtopic.php?f=13&t=6382&p=27514

Previous versions were much more relaxed about what could be in the partition
table, erroring out avoids unexpected changes on upgrade like different
partition offsets.

components/partition_table/Kconfig.projbuild
components/partition_table/gen_esp32part.py
components/partition_table/test_gen_esp32part_host/gen_esp32part_tests.py
docs/en/api-guides/partition-tables.rst

index f50de7aafc8c9f8e2b7083d9fc1cab535e02ee58..0d0351f26bf5d8dd2518fae3d5b54c24cab8eb88 100644 (file)
@@ -45,7 +45,8 @@ config PARTITION_TABLE_OFFSET
 
         This number should be a multiple of 0x1000.
 
-        Note that partition offsets in the partition table CSV file may need to be changed if this value is set to a higher value.
+        Note that partition offsets in the partition table CSV file may need to be changed if this value is set to a higher value. To have
+        each partition offset adapt to the configured partition table offset, leave all partition offsets blank in the CSV file.
 
 config PARTITION_TABLE_MD5
     bool "Generate an MD5 checksum for the partition table"
index 2eefa2c9f4935a3684a90b0185ce11c687ab0c1a..7124559d3b27de4ce64d134ad068fb8252cfc026 100755 (executable)
@@ -96,19 +96,23 @@ class PartitionTable(list):
             if line.startswith("#") or len(line) == 0:
                 continue
             try:
-                res.append(PartitionDefinition.from_csv(line))
+                res.append(PartitionDefinition.from_csv(line, line_no+1))
             except InputError as e:
                 raise InputError("Error at line %d: %s" % (line_no+1, e))
             except Exception:
-                critical("Unexpected error parsing line %d: %s" % (line_no+1, line))
+                critical("Unexpected error parsing CSV line %d: %s" % (line_no+1, line))
                 raise
 
         # fix up missing offsets & negative sizes
         last_end = offset_part_table + PARTITION_TABLE_SIZE # first offset after partition table
         for e in res:
-            if offset_part_table != 0 and e.offset is not None and e.offset < last_end:
-                critical("WARNING: 0x%x address in the partition table is below 0x%x" % (e.offset, last_end))
-                e.offset = None
+            if e.offset is not None and e.offset < last_end:
+                if e == res[0]:
+                    raise InputError("CSV Error: First partition offset 0x%x overlaps end of partition table 0x%x"
+                                     % (e.offset, last_end))
+                else:
+                    raise InputError("CSV Error: Partitions overlap. Partition at line %d sets offset 0x%x. Previous partition ends 0x%x"
+                                     % (e.line_no, e.offset, last_end))
             if e.offset is None:
                 pad_to = 0x10000 if e.type == APP_TYPE else 4
                 if last_end % pad_to != 0:
@@ -246,12 +250,13 @@ class PartitionDefinition(object):
         self.encrypted = False
 
     @classmethod
-    def from_csv(cls, line):
+    def from_csv(cls, line, line_no):
         """ Parse a line from the CSV """
         line_w_defaults = line + ",,,,"  # lazy way to support default fields
         fields = [ f.strip() for f in line_w_defaults.split(",") ]
 
         res = PartitionDefinition()
+        res.line_no = line_no
         res.name = fields[0]
         res.type = res.parse_type(fields[1])
         res.subtype = res.parse_subtype(fields[2])
index 4bd619fc0bf77257b5f0309b6ef1718680d9922e..9f50f24652cffc31a7442c0c8ab865f1fd5e7ef4 100755 (executable)
@@ -162,8 +162,8 @@ second, data, 0x15,         ,  1M
 first, app, factory, 0x100000, 2M
 second, app, ota_0,  0x200000, 1M
 """
-        t = PartitionTable.from_csv(csv)
         with self.assertRaisesRegexp(InputError, "overlap"):
+            t = PartitionTable.from_csv(csv)
             t.verify()
 
 class BinaryOutputTests(unittest.TestCase):
index 14e5bc984b6cfa1fbb442f0e91b1400ab99d9dc4..67539a8221aa3ae167ddd022e05f107e776959d7 100644 (file)
@@ -4,7 +4,7 @@ Partition Tables
 Overview
 --------
 
-A single ESP32'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 offset 0x8000 in the flash.
+A single ESP32'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 (:envvar:`default offset <CONFIG_PARTITION_TABLE_OFFSET>`) 0x8000 in the flash.
 
 Partition table length is 0xC00 bytes (maximum 95 partition table entries). An MD5 checksum is appended after the table data. If the partition table is signed due to `secure boot`, the signature is appended after the partition table.
 
@@ -63,7 +63,7 @@ The CSV format is the same format as printed in the summaries shown above. Howev
 
 * Whitespace between fields is ignored, and so is any line starting with # (comments).
 * Each non-comment line in the CSV file is a partition definition.
-* Only the offset for the first partition is supplied. The gen_esp32part.py tool fills in each remaining offset to start after the preceding partition.
+* 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.
 
 Name field
 ~~~~~~~~~~
@@ -121,12 +121,14 @@ Other data subtypes are reserved for future esp-idf uses.
 Offset & Size
 ~~~~~~~~~~~~~
 
-Only the first offset field is required (we recommend using 0x10000). Partitions with blank offsets will start after the previous partition.
+Partitions with blank offsets will start after the previous partition, or after the partition table in the case of the first partition.
 
 App partitions have to be at offsets aligned to 0x10000 (64K). If you leave the offset field blank, the tool will automatically align the partition. If you specify an unaligned offset for an app partition, the tool will return an error.
 
 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).
 
+If you want the partitions in the partition table to work with any starting offset (:envvar:`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).
+
 Generating Binary Partition Table
 ---------------------------------