Skip to content

Commit 598e07b

Browse files
committed
fix(chip_type_verification): Enable in SDM, do not rely on magic numbers
Closes espressif#1008
1 parent 3555fe1 commit 598e07b

18 files changed

+80
-94
lines changed

esptool/cmds.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@ def check_if_stub(instance):
108108
try:
109109
print("Detecting chip type...", end="")
110110
chip_id = detect_port.get_chip_id()
111-
for cls in [
112-
n for n in ROM_LIST if n.CHIP_NAME not in ("ESP8266", "ESP32", "ESP32-S2")
113-
]:
111+
for cls in ROM_LIST:
114112
# cmd not supported on ESP8266 and ESP32 + ESP32-S2 doesn't return chip_id
113+
if cls.USES_MAGIC_VALUE:
114+
continue
115115
if chip_id == cls.IMAGE_CHIP_ID:
116116
inst = cls(detect_port._port, baud, trace_enabled=trace_enabled)
117117
try:
@@ -144,11 +144,12 @@ def check_if_stub(instance):
144144
)
145145

146146
for cls in ROM_LIST:
147-
if chip_magic_value in cls.CHIP_DETECT_MAGIC_VALUE:
147+
if not cls.USES_MAGIC_VALUE:
148+
continue
149+
if chip_magic_value == cls.MAGIC_VALUE:
148150
inst = cls(detect_port._port, baud, trace_enabled=trace_enabled)
149151
inst = check_if_stub(inst)
150152
inst._post_connect()
151-
inst.check_chip_id()
152153
break
153154
else:
154155
err_msg = f"Unexpected chip magic value {chip_magic_value:#010x}."

esptool/loader.py

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,6 @@ def stub_and_esp32_function_only(func):
143143
)
144144

145145

146-
def esp32s3_or_newer_function_only(func):
147-
"""Attribute for a function only supported by ESP32S3 and later chips ROM"""
148-
return check_supported_function(
149-
func, lambda o: o.CHIP_NAME not in ["ESP8266", "ESP32", "ESP32-S2"]
150-
)
151-
152-
153146
class StubFlasher:
154147
STUB_DIR = os.path.join(os.path.dirname(__file__), "targets", "stub_flasher")
155148
# directories will be searched in the order of STUB_SUBDIRS
@@ -302,6 +295,9 @@ class ESPLoader(object):
302295
# Number of attempts to write flash data
303296
WRITE_FLASH_ATTEMPTS = 2
304297

298+
# Chip uses magic number for chip type autodetection
299+
USES_MAGIC_VALUE = True
300+
305301
def __init__(self, port=DEFAULT_PORT, baud=ESP_ROM_BAUD, trace_enabled=False):
306302
"""Base constructor for ESPLoader bootloader interaction
307303
@@ -752,41 +748,75 @@ def connect(
752748
)
753749

754750
if not detecting:
755-
try:
756-
from .targets import ROM_LIST
751+
from .targets import ROM_LIST
757752

758-
# check the date code registers match what we expect to see
753+
# Perform a dummy read_reg to check if the chip is in secure download mode
754+
try:
759755
chip_magic_value = self.read_reg(ESPLoader.CHIP_DETECT_MAGIC_REG_ADDR)
760-
if chip_magic_value not in self.CHIP_DETECT_MAGIC_VALUE:
761-
actually = None
762-
for cls in ROM_LIST:
763-
if chip_magic_value in cls.CHIP_DETECT_MAGIC_VALUE:
764-
actually = cls
765-
break
766-
if warnings and actually is None:
767-
print(
768-
"WARNING: This chip doesn't appear to be a %s "
769-
"(chip magic value 0x%08x). "
770-
"Probably it is unsupported by this version of esptool."
771-
% (self.CHIP_NAME, chip_magic_value)
772-
)
773-
else:
774-
raise FatalError(
775-
"This chip is %s not %s. Wrong --chip argument?"
776-
% (actually.CHIP_NAME, self.CHIP_NAME)
777-
)
778756
except UnsupportedCommandError:
779757
self.secure_download_mode = True
780758

759+
# Check if chip supports reading chip ID from the get_security_info command
781760
try:
782-
self.check_chip_id()
783-
except UnsupportedCommandError:
784-
# Fix for ROM not responding in SDM, reconnect and try again
785-
if self.secure_download_mode:
786-
self._connect_attempt(mode, reset_sequence[0])
787-
self.check_chip_id()
761+
chip_id = self.get_chip_id()
762+
except (UnsupportedCommandError, struct.error, FatalError):
763+
chip_id = None
764+
765+
detected = None
766+
chip_arg_wrong = False
767+
768+
# If we can read chip ID (ESP32-S3 and later), verify the ID
769+
if chip_id and (self.USES_MAGIC_VALUE or chip_id != self.IMAGE_CHIP_ID):
770+
chip_arg_wrong = True
771+
for cls in ROM_LIST:
772+
if not cls.USES_MAGIC_VALUE and chip_id == cls.IMAGE_CHIP_ID:
773+
detected = cls
774+
break
775+
# If we can't read chip ID (ESP8266, ESP32, ESP32-S2),
776+
# try to verify the chip by magic value
777+
elif (
778+
not chip_id
779+
and not self.secure_download_mode
780+
and (not self.USES_MAGIC_VALUE or chip_magic_value != self.MAGIC_VALUE)
781+
):
782+
chip_arg_wrong = True
783+
for cls in ROM_LIST:
784+
if cls.USES_MAGIC_VALUE and chip_magic_value == cls.MAGIC_VALUE:
785+
detected = cls
786+
break
787+
# If we can't read chip ID and the chip is in SDM (ESP32 or ESP32-S2),
788+
# we can't verify
789+
elif not chip_id and self.secure_download_mode:
790+
if self.CHIP_NAME not in ["ESP32", "ESP32-S2"]:
791+
chip_arg_wrong = True
792+
detected = "ESP32 or ESP32-S2"
788793
else:
789-
raise
794+
print(
795+
f"WARNING: Can't verify this chip is {self.CHIP_NAME} "
796+
"because of active Secure Download Mode. "
797+
"Please check it manually."
798+
)
799+
800+
if chip_arg_wrong:
801+
if warnings and detected is None:
802+
specifier = (
803+
f"(read chip ID {chip_id})"
804+
if chip_id
805+
else f"(read chip magic value {chip_magic_value:#08x})"
806+
)
807+
print(
808+
f"WARNING: This chip doesn't appear to be an {self.CHIP_NAME} "
809+
f"{specifier}. Probably it is unsupported by this version "
810+
"of esptool. Will attempt to continue anyway."
811+
)
812+
else:
813+
chip_type = (
814+
detected if isinstance(detected, str) else detected.CHIP_NAME
815+
)
816+
raise FatalError(
817+
f"This chip is {chip_type}, not {self.CHIP_NAME}. "
818+
"Wrong --chip argument?"
819+
)
790820
self._post_connect()
791821

792822
def _post_connect(self):
@@ -1002,7 +1032,6 @@ def get_security_info(self):
10021032
"api_version": None if esp32s2 else res[10],
10031033
}
10041034

1005-
@esp32s3_or_newer_function_only
10061035
def get_chip_id(self):
10071036
if self.cache["chip_id"] is None:
10081037
res = self.check_command(
@@ -1552,23 +1581,6 @@ def soft_reset(self, stay_in_bootloader):
15521581
# in the stub loader
15531582
self.command(self.ESP_RUN_USER_CODE, wait_response=False)
15541583

1555-
def check_chip_id(self):
1556-
try:
1557-
chip_id = self.get_chip_id()
1558-
if chip_id != self.IMAGE_CHIP_ID:
1559-
print(
1560-
"WARNING: Chip ID {} ({}) doesn't match expected Chip ID {}. "
1561-
"esptool may not work correctly.".format(
1562-
chip_id,
1563-
self.UNSUPPORTED_CHIPS.get(chip_id, "Unknown"),
1564-
self.IMAGE_CHIP_ID,
1565-
)
1566-
)
1567-
# Try to flash anyways by disabling stub
1568-
self.stub_is_disabled = True
1569-
except NotImplementedInROMError:
1570-
pass
1571-
15721584

15731585
def slip_reader(port, trace_function):
15741586
"""Generator to read SLIP packets from a serial port.

esptool/targets/esp32.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ESP32ROM(ESPLoader):
1818
IMAGE_CHIP_ID = 0
1919
IS_STUB = False
2020

21-
CHIP_DETECT_MAGIC_VALUE = [0x00F01D83]
21+
MAGIC_VALUE = 0x00F01D83
2222

2323
IROM_MAP_START = 0x400D0000
2424
IROM_MAP_END = 0x40400000

esptool/targets/esp32c2.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ class ESP32C2ROM(ESP32C3ROM):
2121
DROM_MAP_START = 0x3C000000
2222
DROM_MAP_END = 0x3C400000
2323

24-
# Magic value for ESP32C2 ECO0 , ECO1 and ECO4 respectively
25-
CHIP_DETECT_MAGIC_VALUE = [0x6F51306F, 0x7C41A06F, 0x0C21E06F]
26-
2724
EFUSE_BASE = 0x60008800
2825
EFUSE_BLOCK2_ADDR = EFUSE_BASE + 0x040
2926
MAC_EFUSE_REG = EFUSE_BASE + 0x040

esptool/targets/esp32c3.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,9 @@ class ESP32C3ROM(ESP32ROM):
3030

3131
SPI_ADDR_REG_MSB = False
3232

33-
BOOTLOADER_FLASH_OFFSET = 0x0
33+
USES_MAGIC_VALUE = False
3434

35-
# Magic values for ESP32-C3 eco 1+2, eco 3, eco 6, and eco 7 respectively
36-
CHIP_DETECT_MAGIC_VALUE = [0x6921506F, 0x1B31506F, 0x4881606F, 0x4361606F]
35+
BOOTLOADER_FLASH_OFFSET = 0x0
3736

3837
UART_DATE_REG_ADDR = 0x60000000 + 0x7C
3938

esptool/targets/esp32c5.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ class ESP32C5ROM(ESP32C6ROM):
5454

5555
UARTDEV_BUF_NO = 0x4085F51C # Variable in ROM .bss which indicates the port in use
5656

57-
# Magic values for ESP32C5 ECO0 and ECO1, respectively
58-
CHIP_DETECT_MAGIC_VALUE = [0x1101406F, 0x63E1406F]
59-
6057
FLASH_FREQUENCY = {
6158
"80m": 0xF,
6259
"40m": 0x0,

esptool/targets/esp32c5beta3.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ class ESP32C5BETA3ROM(ESP32C6ROM):
1919
DROM_MAP_START = 0x41000000
2020
DROM_MAP_END = 0x41800000
2121

22-
# Magic value for ESP32C5(beta3)
23-
CHIP_DETECT_MAGIC_VALUE = [0xE10D8082]
24-
2522
FLASH_FREQUENCY = {
2623
"80m": 0xF,
2724
"40m": 0x0,

esptool/targets/esp32c6.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ class ESP32C6ROM(ESP32C3ROM):
2121

2222
BOOTLOADER_FLASH_OFFSET = 0x0
2323

24-
# Magic value for ESP32C6
25-
CHIP_DETECT_MAGIC_VALUE = [0x2CE0806F]
26-
2724
SPI_REG_BASE = 0x60003000
2825
SPI_USR_OFFS = 0x18
2926
SPI_USR1_OFFS = 0x1C

esptool/targets/esp32c61.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ class ESP32C61ROM(ESP32C6ROM):
1212
CHIP_NAME = "ESP32-C61"
1313
IMAGE_CHIP_ID = 20
1414

15-
# Magic value for ESP32C61
16-
CHIP_DETECT_MAGIC_VALUE = [0x33F0206F, 0x2421606F]
17-
1815
UART_DATE_REG_ADDR = 0x60000000 + 0x7C
1916

2017
EFUSE_BASE = 0x600B4800

esptool/targets/esp32c6beta.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ class ESP32C6BETAROM(ESP32C3ROM):
1010
CHIP_NAME = "ESP32-C6(beta)"
1111
IMAGE_CHIP_ID = 7
1212

13-
CHIP_DETECT_MAGIC_VALUE = [0x0DA1806F]
14-
1513
UART_DATE_REG_ADDR = 0x00000500
1614

1715
def get_chip_description(self):

0 commit comments

Comments
 (0)