]> granicus.if.org Git - esp-idf/commitdiff
partition_table: Pad generated table to 0xC00 length, for easier signing
authorAngus Gratton <angus@espressif.com>
Mon, 7 Nov 2016 04:32:21 +0000 (15:32 +1100)
committerAngus Gratton <angus@espressif.com>
Mon, 14 Nov 2016 00:08:42 +0000 (11:08 +1100)
components/partition_table/gen_esp32part.py
components/partition_table/tests/gen_esp32part_tests.py
docs/partition-tables.rst

index 8b5df2b3b5b17303faab4bd6a16335b77edae9fa..b399f31b7844d40cc02a7bc9b180dd82c5de0821 100755 (executable)
@@ -9,6 +9,8 @@ import struct
 import argparse
 import sys
 
+MAX_PARTITION_LENGTH = 0xC00   # 3K for partition data (96 entries) leaves 1K in a 4K sector for signature
+
 __version__ = '1.0'
 
 quiet = False
@@ -92,7 +94,11 @@ class PartitionTable(list):
         return result
 
     def to_binary(self):
-        return "".join(e.to_binary() for e in self)
+        result = "".join(e.to_binary() for e in self)
+        if len(result )>= MAX_PARTITION_LENGTH:
+            raise InputError("Binary partition table length (%d) longer than max" % len(result))
+        result += "\xFF" * (MAX_PARTITION_LENGTH - len(result))  # pad the sector, for signing
+        return result
 
     def to_csv(self, simple_formatting=False):
         rows = [ "# Espressif ESP32 Partition Table",
index 413f1aac912c7c83df08b1d58a1a7fae66c41fe3..d12539ea8755d7379a2e78b9c6ee01ace514f39e 100755 (executable)
@@ -37,6 +37,10 @@ LONGER_BINARY_TABLE += "\xAA\x50\x10\x00" + \
                        "second" + ("\0"*10) + \
                        "\x00\x00\x00\x00"
 
+def _strip_trailing_ffs(binary_table):
+    while binary_table.endswith("\xFF"):
+        binary_table = binary_table[0:len(binary_table)-1]
+    return binary_table
 
 class CSVParserTests(unittest.TestCase):
 
@@ -156,7 +160,7 @@ class BinaryOutputTests(unittest.TestCase):
 first, 0x30, 0xEE, 0x100400, 0x300000
 """
         t = PartitionTable.from_csv(csv)
-        tb = t.to_binary()
+        tb = _strip_trailing_ffs(t.to_binary())
         self.assertEqual(len(tb), 32)
         self.assertEqual('\xAA\x50', tb[0:2]) # magic
         self.assertEqual('\x30\xee', tb[2:4]) # type, subtype
@@ -170,7 +174,7 @@ first, 0x30, 0xEE, 0x100400, 0x300000
 second,0x31, 0xEF,         , 0x100000
 """
         t = PartitionTable.from_csv(csv)
-        tb = t.to_binary()
+        tb = _strip_trailing_ffs(t.to_binary())
         self.assertEqual(len(tb), 64)
         self.assertEqual('\xAA\x50', tb[0:2])
         self.assertEqual('\xAA\x50', tb[32:34])
@@ -215,7 +219,7 @@ class BinaryParserTests(unittest.TestCase):
         self.assertEqual(t[2].type, 0x10)
         self.assertEqual(t[2].name, "second")
 
-        round_trip = t.to_binary()
+        round_trip = _strip_trailing_ffs(t.to_binary())
         self.assertEqual(round_trip, LONGER_BINARY_TABLE)
 
     def test_bad_magic(self):
@@ -267,7 +271,7 @@ class CSVOutputTests(unittest.TestCase):
         self.assertEqual(row[0], "factory")
         self.assertEqual(row[1], "app")
         self.assertEqual(row[2], "2")
-        self.assertEqual(row[3], "64K")
+        self.assertEqual(row[3], "0x10000")
         self.assertEqual(row[4], "1M")
 
         # round trip back to a PartitionTable and check is identical
@@ -291,7 +295,7 @@ class CommandLineTests(unittest.TestCase):
             # reopen the CSV and check the generated binary is identical
             with open(csvpath, 'r') as f:
                 from_csv = PartitionTable.from_csv(f.read())
-            self.assertEqual(from_csv.to_binary(), LONGER_BINARY_TABLE)
+            self.assertEqual(_strip_trailing_ffs(from_csv.to_binary()), LONGER_BINARY_TABLE)
 
             # run gen_esp32part.py to conver the CSV to binary again
             subprocess.check_call([sys.executable, "../gen_esp32part.py",
@@ -299,6 +303,7 @@ class CommandLineTests(unittest.TestCase):
             # assert that file reads back as identical
             with open(binpath, 'rb') as f:
                 binary_readback = f.read()
+            binary_readback = _strip_trailing_ffs(binary_readback)
             self.assertEqual(binary_readback, LONGER_BINARY_TABLE)
 
         finally:
index 88597532d2bbf70a407f8d1b00cc7eb7e22a267a..5f5911bd528b88086d19f4aecd8b85e53631b21b 100644 (file)
@@ -6,6 +6,8 @@ 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 0x4000 in the flash.
 
+Partition table length is 0xC00 bytes (maximum 95 partition table entries). If the partition table is signed due to `secure boot`, the signature is appended after the table data.
+
 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.
 
 The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables:
@@ -130,3 +132,6 @@ Flashing the partition table
 * ``make flash``: Will flash everything including the partition table.
 
 A manual flashing command is also printed as part of ``make partition_table``.
+
+
+.. _secure boot: security/secure-boot.rst