Skip to content

Commit

Permalink
fix(chip_type_verification): Enable in SDM, do not rely on magic numbers
Browse files Browse the repository at this point in the history
Closes #1008
  • Loading branch information
radimkarnis committed Dec 11, 2024
1 parent 3555fe1 commit 598e07b
Show file tree
Hide file tree
Showing 18 changed files with 80 additions and 94 deletions.
11 changes: 6 additions & 5 deletions esptool/cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ def check_if_stub(instance):
try:
print("Detecting chip type...", end="")
chip_id = detect_port.get_chip_id()
for cls in [
n for n in ROM_LIST if n.CHIP_NAME not in ("ESP8266", "ESP32", "ESP32-S2")
]:
for cls in ROM_LIST:
# cmd not supported on ESP8266 and ESP32 + ESP32-S2 doesn't return chip_id
if cls.USES_MAGIC_VALUE:
continue
if chip_id == cls.IMAGE_CHIP_ID:
inst = cls(detect_port._port, baud, trace_enabled=trace_enabled)
try:
Expand Down Expand Up @@ -144,11 +144,12 @@ def check_if_stub(instance):
)

for cls in ROM_LIST:
if chip_magic_value in cls.CHIP_DETECT_MAGIC_VALUE:
if not cls.USES_MAGIC_VALUE:
continue
if chip_magic_value == cls.MAGIC_VALUE:
inst = cls(detect_port._port, baud, trace_enabled=trace_enabled)
inst = check_if_stub(inst)
inst._post_connect()
inst.check_chip_id()
break
else:
err_msg = f"Unexpected chip magic value {chip_magic_value:#010x}."
Expand Down
118 changes: 65 additions & 53 deletions esptool/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,6 @@ def stub_and_esp32_function_only(func):
)


def esp32s3_or_newer_function_only(func):
"""Attribute for a function only supported by ESP32S3 and later chips ROM"""
return check_supported_function(
func, lambda o: o.CHIP_NAME not in ["ESP8266", "ESP32", "ESP32-S2"]
)


class StubFlasher:
STUB_DIR = os.path.join(os.path.dirname(__file__), "targets", "stub_flasher")
# directories will be searched in the order of STUB_SUBDIRS
Expand Down Expand Up @@ -302,6 +295,9 @@ class ESPLoader(object):
# Number of attempts to write flash data
WRITE_FLASH_ATTEMPTS = 2

# Chip uses magic number for chip type autodetection
USES_MAGIC_VALUE = True

def __init__(self, port=DEFAULT_PORT, baud=ESP_ROM_BAUD, trace_enabled=False):
"""Base constructor for ESPLoader bootloader interaction
Expand Down Expand Up @@ -752,41 +748,75 @@ def connect(
)

if not detecting:
try:
from .targets import ROM_LIST
from .targets import ROM_LIST

# check the date code registers match what we expect to see
# Perform a dummy read_reg to check if the chip is in secure download mode
try:
chip_magic_value = self.read_reg(ESPLoader.CHIP_DETECT_MAGIC_REG_ADDR)
if chip_magic_value not in self.CHIP_DETECT_MAGIC_VALUE:
actually = None
for cls in ROM_LIST:
if chip_magic_value in cls.CHIP_DETECT_MAGIC_VALUE:
actually = cls
break
if warnings and actually is None:
print(
"WARNING: This chip doesn't appear to be a %s "
"(chip magic value 0x%08x). "
"Probably it is unsupported by this version of esptool."
% (self.CHIP_NAME, chip_magic_value)
)
else:
raise FatalError(
"This chip is %s not %s. Wrong --chip argument?"
% (actually.CHIP_NAME, self.CHIP_NAME)
)
except UnsupportedCommandError:
self.secure_download_mode = True

# Check if chip supports reading chip ID from the get_security_info command
try:
self.check_chip_id()
except UnsupportedCommandError:
# Fix for ROM not responding in SDM, reconnect and try again
if self.secure_download_mode:
self._connect_attempt(mode, reset_sequence[0])
self.check_chip_id()
chip_id = self.get_chip_id()
except (UnsupportedCommandError, struct.error, FatalError):
chip_id = None

detected = None
chip_arg_wrong = False

# If we can read chip ID (ESP32-S3 and later), verify the ID
if chip_id and (self.USES_MAGIC_VALUE or chip_id != self.IMAGE_CHIP_ID):
chip_arg_wrong = True
for cls in ROM_LIST:
if not cls.USES_MAGIC_VALUE and chip_id == cls.IMAGE_CHIP_ID:
detected = cls
break
# If we can't read chip ID (ESP8266, ESP32, ESP32-S2),
# try to verify the chip by magic value
elif (
not chip_id
and not self.secure_download_mode
and (not self.USES_MAGIC_VALUE or chip_magic_value != self.MAGIC_VALUE)
):
chip_arg_wrong = True
for cls in ROM_LIST:
if cls.USES_MAGIC_VALUE and chip_magic_value == cls.MAGIC_VALUE:
detected = cls
break
# If we can't read chip ID and the chip is in SDM (ESP32 or ESP32-S2),
# we can't verify
elif not chip_id and self.secure_download_mode:
if self.CHIP_NAME not in ["ESP32", "ESP32-S2"]:
chip_arg_wrong = True
detected = "ESP32 or ESP32-S2"
else:
raise
print(
f"WARNING: Can't verify this chip is {self.CHIP_NAME} "
"because of active Secure Download Mode. "
"Please check it manually."
)

if chip_arg_wrong:
if warnings and detected is None:
specifier = (
f"(read chip ID {chip_id})"
if chip_id
else f"(read chip magic value {chip_magic_value:#08x})"
)
print(
f"WARNING: This chip doesn't appear to be an {self.CHIP_NAME} "
f"{specifier}. Probably it is unsupported by this version "
"of esptool. Will attempt to continue anyway."
)
else:
chip_type = (
detected if isinstance(detected, str) else detected.CHIP_NAME
)
raise FatalError(
f"This chip is {chip_type}, not {self.CHIP_NAME}. "
"Wrong --chip argument?"
)
self._post_connect()

def _post_connect(self):
Expand Down Expand Up @@ -1002,7 +1032,6 @@ def get_security_info(self):
"api_version": None if esp32s2 else res[10],
}

@esp32s3_or_newer_function_only
def get_chip_id(self):
if self.cache["chip_id"] is None:
res = self.check_command(
Expand Down Expand Up @@ -1552,23 +1581,6 @@ def soft_reset(self, stay_in_bootloader):
# in the stub loader
self.command(self.ESP_RUN_USER_CODE, wait_response=False)

def check_chip_id(self):
try:
chip_id = self.get_chip_id()
if chip_id != self.IMAGE_CHIP_ID:
print(
"WARNING: Chip ID {} ({}) doesn't match expected Chip ID {}. "
"esptool may not work correctly.".format(
chip_id,
self.UNSUPPORTED_CHIPS.get(chip_id, "Unknown"),
self.IMAGE_CHIP_ID,
)
)
# Try to flash anyways by disabling stub
self.stub_is_disabled = True
except NotImplementedInROMError:
pass


def slip_reader(port, trace_function):
"""Generator to read SLIP packets from a serial port.
Expand Down
2 changes: 1 addition & 1 deletion esptool/targets/esp32.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ESP32ROM(ESPLoader):
IMAGE_CHIP_ID = 0
IS_STUB = False

CHIP_DETECT_MAGIC_VALUE = [0x00F01D83]
MAGIC_VALUE = 0x00F01D83

IROM_MAP_START = 0x400D0000
IROM_MAP_END = 0x40400000
Expand Down
3 changes: 0 additions & 3 deletions esptool/targets/esp32c2.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ class ESP32C2ROM(ESP32C3ROM):
DROM_MAP_START = 0x3C000000
DROM_MAP_END = 0x3C400000

# Magic value for ESP32C2 ECO0 , ECO1 and ECO4 respectively
CHIP_DETECT_MAGIC_VALUE = [0x6F51306F, 0x7C41A06F, 0x0C21E06F]

EFUSE_BASE = 0x60008800
EFUSE_BLOCK2_ADDR = EFUSE_BASE + 0x040
MAC_EFUSE_REG = EFUSE_BASE + 0x040
Expand Down
5 changes: 2 additions & 3 deletions esptool/targets/esp32c3.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ class ESP32C3ROM(ESP32ROM):

SPI_ADDR_REG_MSB = False

BOOTLOADER_FLASH_OFFSET = 0x0
USES_MAGIC_VALUE = False

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

UART_DATE_REG_ADDR = 0x60000000 + 0x7C

Expand Down
3 changes: 0 additions & 3 deletions esptool/targets/esp32c5.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ class ESP32C5ROM(ESP32C6ROM):

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

# Magic values for ESP32C5 ECO0 and ECO1, respectively
CHIP_DETECT_MAGIC_VALUE = [0x1101406F, 0x63E1406F]

FLASH_FREQUENCY = {
"80m": 0xF,
"40m": 0x0,
Expand Down
3 changes: 0 additions & 3 deletions esptool/targets/esp32c5beta3.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ class ESP32C5BETA3ROM(ESP32C6ROM):
DROM_MAP_START = 0x41000000
DROM_MAP_END = 0x41800000

# Magic value for ESP32C5(beta3)
CHIP_DETECT_MAGIC_VALUE = [0xE10D8082]

FLASH_FREQUENCY = {
"80m": 0xF,
"40m": 0x0,
Expand Down
3 changes: 0 additions & 3 deletions esptool/targets/esp32c6.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ class ESP32C6ROM(ESP32C3ROM):

BOOTLOADER_FLASH_OFFSET = 0x0

# Magic value for ESP32C6
CHIP_DETECT_MAGIC_VALUE = [0x2CE0806F]

SPI_REG_BASE = 0x60003000
SPI_USR_OFFS = 0x18
SPI_USR1_OFFS = 0x1C
Expand Down
3 changes: 0 additions & 3 deletions esptool/targets/esp32c61.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ class ESP32C61ROM(ESP32C6ROM):
CHIP_NAME = "ESP32-C61"
IMAGE_CHIP_ID = 20

# Magic value for ESP32C61
CHIP_DETECT_MAGIC_VALUE = [0x33F0206F, 0x2421606F]

UART_DATE_REG_ADDR = 0x60000000 + 0x7C

EFUSE_BASE = 0x600B4800
Expand Down
2 changes: 0 additions & 2 deletions esptool/targets/esp32c6beta.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ class ESP32C6BETAROM(ESP32C3ROM):
CHIP_NAME = "ESP32-C6(beta)"
IMAGE_CHIP_ID = 7

CHIP_DETECT_MAGIC_VALUE = [0x0DA1806F]

UART_DATE_REG_ADDR = 0x00000500

def get_chip_description(self):
Expand Down
3 changes: 0 additions & 3 deletions esptool/targets/esp32h2.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ class ESP32H2ROM(ESP32C6ROM):
CHIP_NAME = "ESP32-H2"
IMAGE_CHIP_ID = 16

# Magic value for ESP32H2
CHIP_DETECT_MAGIC_VALUE = [0xD7B73E80]

DR_REG_LP_WDT_BASE = 0x600B1C00
RTC_CNTL_WDTCONFIG0_REG = DR_REG_LP_WDT_BASE + 0x0 # LP_WDT_RWDT_CONFIG0_REG
RTC_CNTL_WDTCONFIG1_REG = DR_REG_LP_WDT_BASE + 0x0004 # LP_WDT_RWDT_CONFIG1_REG
Expand Down
2 changes: 0 additions & 2 deletions esptool/targets/esp32h2beta1.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ class ESP32H2BETA1ROM(ESP32C3ROM):

BOOTLOADER_FLASH_OFFSET = 0x0

CHIP_DETECT_MAGIC_VALUE = [0xCA26CC22]

UART_DATE_REG_ADDR = 0x60000000 + 0x7C

EFUSE_BASE = 0x6001A000
Expand Down
2 changes: 0 additions & 2 deletions esptool/targets/esp32h2beta2.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ class ESP32H2BETA2ROM(ESP32H2BETA1ROM):
CHIP_NAME = "ESP32-H2(beta2)"
IMAGE_CHIP_ID = 14

CHIP_DETECT_MAGIC_VALUE = [0x6881B06F]

def get_chip_description(self):
chip_name = {
1: "ESP32-H2(beta2)",
Expand Down
4 changes: 2 additions & 2 deletions esptool/targets/esp32p4.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ class ESP32P4ROM(ESP32ROM):

BOOTLOADER_FLASH_OFFSET = 0x2000 # First 2 sectors are reserved for FE purposes

CHIP_DETECT_MAGIC_VALUE = [0x0, 0x0ADDBAD0]

UART_DATE_REG_ADDR = 0x500CA000 + 0x8C

EFUSE_BASE = 0x5012D000
Expand All @@ -40,6 +38,8 @@ class ESP32P4ROM(ESP32ROM):

SPI_ADDR_REG_MSB = False

USES_MAGIC_VALUE = False

EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address

EFUSE_PURPOSE_KEY0_REG = EFUSE_BASE + 0x34
Expand Down
2 changes: 1 addition & 1 deletion esptool/targets/esp32s2.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ESP32S2ROM(ESP32ROM):
DROM_MAP_START = 0x3F000000
DROM_MAP_END = 0x3F3F0000

CHIP_DETECT_MAGIC_VALUE = [0x000007C6]
MAGIC_VALUE = 0x000007C6

SPI_REG_BASE = 0x3F402000
SPI_USR_OFFS = 0x18
Expand Down
4 changes: 2 additions & 2 deletions esptool/targets/esp32s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ class ESP32S3ROM(ESP32ROM):

IMAGE_CHIP_ID = 9

CHIP_DETECT_MAGIC_VALUE = [0x9]

IROM_MAP_START = 0x42000000
IROM_MAP_END = 0x44000000
DROM_MAP_START = 0x3C000000
Expand All @@ -35,6 +33,8 @@ class ESP32S3ROM(ESP32ROM):

SPI_ADDR_REG_MSB = False

USES_MAGIC_VALUE = False

BOOTLOADER_FLASH_OFFSET = 0x0

SUPPORTS_ENCRYPTED_FLASH = True
Expand Down
2 changes: 0 additions & 2 deletions esptool/targets/esp32s3beta2.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ class ESP32S3BETA2ROM(ESP32S3ROM):
CHIP_NAME = "ESP32-S3(beta2)"
IMAGE_CHIP_ID = 4

CHIP_DETECT_MAGIC_VALUE = [0xEB004136]

EFUSE_BASE = 0x6001A000 # BLOCK0 read base address


Expand Down
2 changes: 1 addition & 1 deletion esptool/targets/esp8266.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class ESP8266ROM(ESPLoader):
CHIP_NAME = "ESP8266"
IS_STUB = False

CHIP_DETECT_MAGIC_VALUE = [0xFFF0C101]
MAGIC_VALUE = 0xFFF0C101

# OTP ROM addresses
ESP_OTP_MAC0 = 0x3FF00050
Expand Down

0 comments on commit 598e07b

Please sign in to comment.