mirror of
https://github.com/espressif/esptool.git
synced 2025-10-17 16:01:18 +08:00
fix(chip_type_verification): Enable in SDM, do not rely on magic numbers
Closes https://github.com/espressif/esptool/pull/1008
This commit is contained in:
@@ -108,10 +108,10 @@ def detect_chip(
|
||||
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:
|
||||
@@ -144,11 +144,12 @@ def detect_chip(
|
||||
)
|
||||
|
||||
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}."
|
||||
|
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -752,41 +748,75 @@ class ESPLoader(object):
|
||||
)
|
||||
|
||||
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):
|
||||
@@ -1002,7 +1032,6 @@ class ESPLoader(object):
|
||||
"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(
|
||||
@@ -1552,23 +1581,6 @@ class ESPLoader(object):
|
||||
# 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.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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):
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)",
|
||||
|
@@ -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
|
||||
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
@@ -35,6 +33,8 @@ class ESP32S3ROM(ESP32ROM):
|
||||
|
||||
SPI_ADDR_REG_MSB = False
|
||||
|
||||
USES_MAGIC_VALUE = False
|
||||
|
||||
BOOTLOADER_FLASH_OFFSET = 0x0
|
||||
|
||||
SUPPORTS_ENCRYPTED_FLASH = True
|
||||
|
@@ -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
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user