forked from espressif/arduino-esp32
update idf libs, disable WDT on S2, use malloc for PSRAM
This commit is contained in:
290
tools/esptool.py
290
tools/esptool.py
@ -201,7 +201,7 @@ class ESPLoader(object):
|
||||
ESP_FLASH_DEFL_END = 0x12
|
||||
ESP_SPI_FLASH_MD5 = 0x13
|
||||
|
||||
# Commands supported by ESP32S2 ROM bootloader only
|
||||
# Commands supported by ESP32-S2 ROM bootloader only
|
||||
ESP_GET_SECURITY_INFO = 0x14
|
||||
|
||||
# Some commands supported by stub only
|
||||
@ -234,7 +234,7 @@ class ESPLoader(object):
|
||||
FLASH_SECTOR_SIZE = 0x1000
|
||||
|
||||
UART_DATE_REG_ADDR = 0x60000078 # used to differentiate ESP8266 vs ESP32*
|
||||
UART_DATE_REG2_ADDR = 0x3f400074 # used to differentiate ESP32S2 vs other models
|
||||
UART_DATE_REG2_ADDR = 0x3f400074 # used to differentiate ESP32-S2 vs other models
|
||||
|
||||
UART_CLKDIV_MASK = 0xFFFFF
|
||||
|
||||
@ -296,7 +296,7 @@ class ESPLoader(object):
|
||||
connect_mode parameter) as part of querying the chip.
|
||||
"""
|
||||
detect_port = ESPLoader(port, baud, trace_enabled=trace_enabled)
|
||||
detect_port.connect(connect_mode, connect_attempts)
|
||||
detect_port.connect(connect_mode, connect_attempts, detecting=True)
|
||||
try:
|
||||
print('Detecting chip type...', end='')
|
||||
sys.stdout.flush()
|
||||
@ -494,7 +494,7 @@ class ESPLoader(object):
|
||||
last_error = e
|
||||
return last_error
|
||||
|
||||
def connect(self, mode='default_reset', attempts=DEFAULT_CONNECT_ATTEMPTS):
|
||||
def connect(self, mode='default_reset', attempts=DEFAULT_CONNECT_ATTEMPTS, detecting=False):
|
||||
""" Try connecting repeatedly until successful, or giving up """
|
||||
print('Connecting...', end='')
|
||||
sys.stdout.flush()
|
||||
@ -504,13 +504,31 @@ class ESPLoader(object):
|
||||
for _ in range(attempts) if attempts > 0 else itertools.count():
|
||||
last_error = self._connect_attempt(mode=mode, esp32r0_delay=False)
|
||||
if last_error is None:
|
||||
return
|
||||
break
|
||||
last_error = self._connect_attempt(mode=mode, esp32r0_delay=True)
|
||||
if last_error is None:
|
||||
return
|
||||
break
|
||||
finally:
|
||||
print('') # end 'Connecting...' line
|
||||
raise FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error))
|
||||
|
||||
if last_error is not None:
|
||||
raise FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error))
|
||||
|
||||
if not detecting:
|
||||
# check the date code registers match what we expect to see
|
||||
date_reg = self.read_reg(self.UART_DATE_REG_ADDR)
|
||||
date_reg2 = self.read_reg(self.UART_DATE_REG2_ADDR)
|
||||
if date_reg != self.DATE_REG_VALUE or (self.DATE_REG2_VALUE is not None and date_reg2 != self.DATE_REG2_VALUE):
|
||||
actually = None
|
||||
for cls in [ESP8266ROM, ESP32ROM, ESP32S2ROM]:
|
||||
if date_reg == cls.DATE_REG_VALUE and (cls.DATE_REG2_VALUE is None or date_reg2 == cls.DATE_REG2_VALUE):
|
||||
actually = cls
|
||||
break
|
||||
if actually is None:
|
||||
print(("WARNING: This chip doesn't appear to be a %s (date codes 0x%08x:0x%08x). " +
|
||||
"Probably it is unsupported by this version of esptool.") % (self.CHIP_NAME, date_reg, date_reg2))
|
||||
else:
|
||||
raise FatalError("This chip is %s not %s. Wrong --chip argument?" % (actually.CHIP_NAME, self.CHIP_NAME))
|
||||
|
||||
def read_reg(self, addr):
|
||||
""" Read memory address in target """
|
||||
@ -600,7 +618,7 @@ class ESPLoader(object):
|
||||
|
||||
params = struct.pack('<IIII', erase_size, num_blocks, self.FLASH_WRITE_SIZE, offset)
|
||||
if isinstance(self, ESP32S2ROM) and not self.IS_STUB:
|
||||
params += struct.pack('<I', 0) # enter encrypted flash mode (unsupported for now)
|
||||
params += struct.pack('<I', 0) # enter encrypted flash mode (ROM version of this is unsupported for now)
|
||||
self.check_command("enter Flash download mode", self.ESP_FLASH_BEGIN,
|
||||
params, timeout=timeout)
|
||||
if size != 0 and not self.IS_STUB:
|
||||
@ -701,7 +719,7 @@ class ESPLoader(object):
|
||||
print("Compressed %d bytes to %d..." % (size, compsize))
|
||||
params = struct.pack('<IIII', write_size, num_blocks, self.FLASH_WRITE_SIZE, offset)
|
||||
if isinstance(self, ESP32S2ROM) and not self.IS_STUB:
|
||||
params += struct.pack('<I', 0) # enter encrypted flash mode (unsupported for now)
|
||||
params += struct.pack('<I', 0) # extra param is to enter encrypted flash mode via ROM (not supported currently)
|
||||
self.check_command("enter compressed flash mode", self.ESP_FLASH_DEFL_BEGIN, params, timeout=timeout)
|
||||
if size != 0 and not self.IS_STUB:
|
||||
# (stub erases as it writes, but ROM loaders erase on begin)
|
||||
@ -1195,7 +1213,10 @@ class ESP32ROM(ESPLoader):
|
||||
SPI_USR2_OFFS = 0x24
|
||||
SPI_MOSI_DLEN_OFFS = 0x28
|
||||
SPI_MISO_DLEN_OFFS = 0x2c
|
||||
EFUSE_REG_BASE = 0x6001a000
|
||||
EFUSE_RD_REG_BASE = 0x6001a000
|
||||
|
||||
EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG = EFUSE_RD_REG_BASE + 0x18
|
||||
EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT = (1 << 7) # EFUSE_RD_DISABLE_DL_ENCRYPT
|
||||
|
||||
DR_REG_SYSCON_BASE = 0x3ff66000
|
||||
|
||||
@ -1233,6 +1254,8 @@ class ESP32ROM(ESPLoader):
|
||||
[0x400D0000, 0x40400000, "IROM"],
|
||||
[0x50000000, 0x50002000, "RTC_DATA"]]
|
||||
|
||||
FLASH_ENCRYPTED_WRITE_ALIGN = 32
|
||||
|
||||
""" Try to read the BLOCK1 (encryption key) and check if it is valid """
|
||||
|
||||
def is_flash_encryption_key_valid(self):
|
||||
@ -1246,10 +1269,10 @@ class ESP32ROM(ESPLoader):
|
||||
if rd_disable:
|
||||
return True
|
||||
else:
|
||||
""" reading of BLOCK1 is ALLOWED so we will read and verify for non-zero.
|
||||
When ESP32 has not generated AES/encryption key in BLOCK1, the contents will be readable and 0.
|
||||
If the flash encryption is enabled it is expected to have a valid non-zero key. We break out on
|
||||
first occurance of non-zero value """
|
||||
# reading of BLOCK1 is ALLOWED so we will read and verify for non-zero.
|
||||
# When ESP32 has not generated AES/encryption key in BLOCK1, the contents will be readable and 0.
|
||||
# If the flash encryption is enabled it is expected to have a valid non-zero key. We break out on
|
||||
# first occurance of non-zero value
|
||||
key_word = [0] * 7
|
||||
for i in range(len(key_word)):
|
||||
key_word[i] = self.read_efuse(14 + i)
|
||||
@ -1258,15 +1281,14 @@ class ESP32ROM(ESPLoader):
|
||||
return True
|
||||
return False
|
||||
|
||||
""" For flash encryption related commands we need to make sure
|
||||
user has programmed all the relevant efuse correctly so at
|
||||
the end of write_flash_encrypt esptool will verify the values
|
||||
of flash_crypt_config to be non zero if they are not read
|
||||
protected. If the values are zero a warning will be printed
|
||||
"""
|
||||
|
||||
def get_flash_crypt_config(self):
|
||||
""" bit 3 in efuse_rd_disable[3:0] is mapped to flash_crypt_config
|
||||
""" For flash encryption related commands we need to make sure
|
||||
user has programmed all the relevant efuse correctly so before
|
||||
writing encrypted write_flash_encrypt esptool will verify the values
|
||||
of flash_crypt_config to be non zero if they are not read
|
||||
protected. If the values are zero a warning will be printed
|
||||
|
||||
bit 3 in efuse_rd_disable[3:0] is mapped to flash_crypt_config
|
||||
this bit is at position 19 in EFUSE_BLK0_RDATA0_REG """
|
||||
word0 = self.read_efuse(0)
|
||||
rd_disable = (word0 >> 19) & 0x1
|
||||
@ -1281,6 +1303,12 @@ class ESP32ROM(ESPLoader):
|
||||
# if read of the efuse is disabled we assume it is set correctly
|
||||
return 0xF
|
||||
|
||||
def get_encrypted_download_disabled(self):
|
||||
if self.read_reg(self.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG) & self.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_chip_description(self):
|
||||
word3 = self.read_efuse(3)
|
||||
word5 = self.read_efuse(5)
|
||||
@ -1359,7 +1387,7 @@ class ESP32ROM(ESPLoader):
|
||||
|
||||
def read_efuse(self, n):
|
||||
""" Read the nth word of the ESP3x EFUSE region. """
|
||||
return self.read_reg(self.EFUSE_REG_BASE + (4 * n))
|
||||
return self.read_reg(self.EFUSE_RD_REG_BASE + (4 * n))
|
||||
|
||||
def chip_id(self):
|
||||
raise NotSupportedError(self, "chip_id")
|
||||
@ -1416,7 +1444,7 @@ class ESP32ROM(ESPLoader):
|
||||
|
||||
|
||||
class ESP32S2ROM(ESP32ROM):
|
||||
CHIP_NAME = "ESP32S2"
|
||||
CHIP_NAME = "ESP32-S2"
|
||||
IMAGE_CHIP_ID = 2
|
||||
|
||||
IROM_MAP_START = 0x40080000
|
||||
@ -1424,7 +1452,7 @@ class ESP32S2ROM(ESP32ROM):
|
||||
DROM_MAP_START = 0x3F000000
|
||||
DROM_MAP_END = 0x3F3F0000
|
||||
|
||||
DATE_REG_VALUE = 0x00000500 # This is actually UART_ID_REG(0) on ESP32S2
|
||||
DATE_REG_VALUE = 0x00000500 # This is actually UART_ID_REG(0) on ESP32-S2
|
||||
DATE_REG2_VALUE = 0x19031400 # this is the date register
|
||||
|
||||
SPI_REG_BASE = 0x3f402000
|
||||
@ -1435,12 +1463,36 @@ class ESP32S2ROM(ESP32ROM):
|
||||
SPI_MISO_DLEN_OFFS = 0x28
|
||||
SPI_W0_OFFS = 0x58
|
||||
|
||||
EFUSE_REG_BASE = 0x3f41A030 # BLOCK0 read base address
|
||||
|
||||
MAC_EFUSE_REG = 0x3f41A044 # ESP32S2 has special block for MAC efuses
|
||||
MAC_EFUSE_REG = 0x3f41A044 # ESP32-S2 has special block for MAC efuses
|
||||
|
||||
UART_CLKDIV_REG = 0x3f400014
|
||||
|
||||
FLASH_ENCRYPTED_WRITE_ALIGN = 16
|
||||
|
||||
# todo: use espefuse APIs to get this info
|
||||
EFUSE_BASE = 0x3f41A000
|
||||
EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address
|
||||
|
||||
EFUSE_PURPOSE_KEY0_REG = EFUSE_BASE + 0x34
|
||||
EFUSE_PURPOSE_KEY0_SHIFT = 24
|
||||
EFUSE_PURPOSE_KEY1_REG = EFUSE_BASE + 0x34
|
||||
EFUSE_PURPOSE_KEY1_SHIFT = 28
|
||||
EFUSE_PURPOSE_KEY2_REG = EFUSE_BASE + 0x38
|
||||
EFUSE_PURPOSE_KEY2_SHIFT = 0
|
||||
EFUSE_PURPOSE_KEY3_REG = EFUSE_BASE + 0x38
|
||||
EFUSE_PURPOSE_KEY3_SHIFT = 4
|
||||
EFUSE_PURPOSE_KEY4_REG = EFUSE_BASE + 0x38
|
||||
EFUSE_PURPOSE_KEY4_SHIFT = 8
|
||||
EFUSE_PURPOSE_KEY5_REG = EFUSE_BASE + 0x38
|
||||
EFUSE_PURPOSE_KEY5_SHIFT = 12
|
||||
|
||||
EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG = EFUSE_RD_REG_BASE
|
||||
EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT = 1 << 19
|
||||
|
||||
PURPOSE_VAL_XTS_AES256_KEY_1 = 2
|
||||
PURPOSE_VAL_XTS_AES256_KEY_2 = 3
|
||||
PURPOSE_VAL_XTS_AES128_KEY = 4
|
||||
|
||||
def get_chip_description(self):
|
||||
return "ESP32-S2"
|
||||
|
||||
@ -1448,7 +1500,7 @@ class ESP32S2ROM(ESP32ROM):
|
||||
return ["WiFi"]
|
||||
|
||||
def get_crystal_freq(self):
|
||||
# ESP32S2 XTAL is fixed to 40MHz
|
||||
# ESP32-S2 XTAL is fixed to 40MHz
|
||||
return 40
|
||||
|
||||
def override_vddsdio(self, new_voltage):
|
||||
@ -1463,6 +1515,31 @@ class ESP32S2ROM(ESP32ROM):
|
||||
except TypeError: # Python 3, bitstring elements are already bytes
|
||||
return tuple(bitstring)
|
||||
|
||||
def get_flash_crypt_config(self):
|
||||
return None # doesn't exist on ESP32-S2
|
||||
|
||||
def get_key_block_purpose(self, key_block):
|
||||
if key_block < 0 or key_block > 5:
|
||||
raise FatalError("Valid key block numbers must be in range 0-5")
|
||||
|
||||
reg, shift = [(self.EFUSE_PURPOSE_KEY0_REG, self.EFUSE_PURPOSE_KEY0_SHIFT),
|
||||
(self.EFUSE_PURPOSE_KEY1_REG, self.EFUSE_PURPOSE_KEY1_SHIFT),
|
||||
(self.EFUSE_PURPOSE_KEY2_REG, self.EFUSE_PURPOSE_KEY2_SHIFT),
|
||||
(self.EFUSE_PURPOSE_KEY3_REG, self.EFUSE_PURPOSE_KEY3_SHIFT),
|
||||
(self.EFUSE_PURPOSE_KEY4_REG, self.EFUSE_PURPOSE_KEY4_SHIFT),
|
||||
(self.EFUSE_PURPOSE_KEY5_REG, self.EFUSE_PURPOSE_KEY5_SHIFT)][key_block]
|
||||
return (self.read_reg(reg) >> shift) & 0xF
|
||||
|
||||
def is_flash_encryption_key_valid(self):
|
||||
# Need to see either an AES-128 key or two AES-256 keys
|
||||
purposes = [self.get_key_block_purpose(b) for b in range(6)]
|
||||
|
||||
if any(p == self.PURPOSE_VAL_XTS_AES128_KEY for p in purposes):
|
||||
return True
|
||||
|
||||
return any(p == self.PURPOSE_VAL_XTS_AES256_KEY_1 for p in purposes) \
|
||||
and any(p == self.PURPOSE_VAL_XTS_AES256_KEY_2 for p in purposes)
|
||||
|
||||
|
||||
class ESP32StubLoader(ESP32ROM):
|
||||
""" Access class for ESP32 stub loader, runs on top of ROM.
|
||||
@ -1481,7 +1558,7 @@ ESP32ROM.STUB_CLASS = ESP32StubLoader
|
||||
|
||||
|
||||
class ESP32S2StubLoader(ESP32S2ROM):
|
||||
""" Access class for ESP32S2 stub loader, runs on top of ROM.
|
||||
""" Access class for ESP32-S2 stub loader, runs on top of ROM.
|
||||
|
||||
(Basically the same as ESP2StubLoader, but different base class.
|
||||
Can possibly be made into a mixin.)
|
||||
@ -1510,12 +1587,14 @@ class ESPBOOTLOADER(object):
|
||||
|
||||
|
||||
def LoadFirmwareImage(chip, filename):
|
||||
""" Load a firmware image. Can be for ESP8266 or ESP32. ESP8266 images will be examined to determine if they are
|
||||
original ROM firmware images (ESP8266ROMFirmwareImage) or "v2" OTA bootloader images.
|
||||
""" Load a firmware image. Can be for any supported SoC.
|
||||
|
||||
ESP8266 images will be examined to determine if they are original ROM firmware images (ESP8266ROMFirmwareImage)
|
||||
or "v2" OTA bootloader images.
|
||||
|
||||
Returns a BaseFirmwareImage subclass, either ESP8266ROMFirmwareImage (v1) or ESP8266V2FirmwareImage (v2).
|
||||
"""
|
||||
chip = chip.lower()
|
||||
chip = chip.lower().replace("-", "")
|
||||
with open(filename, 'rb') as f:
|
||||
if chip == 'esp32':
|
||||
return ESP32FirmwareImage(f)
|
||||
@ -2471,26 +2550,31 @@ def write_flash(esp, args):
|
||||
# For encrypt option we do few sanity checks before actual flash write
|
||||
if args.encrypt:
|
||||
do_write = True
|
||||
|
||||
if esp.get_encrypted_download_disabled():
|
||||
raise FatalError("This chip has encrypt functionality in UART download mode disabled. "
|
||||
+ "This is the Flash Encryption configuration for Production mode instead of Development mode.")
|
||||
|
||||
crypt_cfg_efuse = esp.get_flash_crypt_config()
|
||||
|
||||
if crypt_cfg_efuse != 0xF:
|
||||
print('\nWARNING: Unexpected FLASH_CRYPT_CONFIG value', hex(crypt_cfg_efuse))
|
||||
print('\nMake sure flash encryption is enabled correctly, refer to Flash Encryption documentation')
|
||||
if crypt_cfg_efuse is not None and crypt_cfg_efuse != 0xF:
|
||||
print('Unexpected FLASH_CRYPT_CONFIG value: 0x%x' % (crypt_cfg_efuse))
|
||||
do_write = False
|
||||
|
||||
enc_key_valid = esp.is_flash_encryption_key_valid()
|
||||
|
||||
if not enc_key_valid:
|
||||
print('\nFlash encryption key is not programmed')
|
||||
print('\nMake sure flash encryption is enabled correctly, refer to Flash Encryption documentation')
|
||||
print('Flash encryption key is not programmed')
|
||||
do_write = False
|
||||
|
||||
if (esp.FLASH_WRITE_SIZE % 32) != 0:
|
||||
print('\nWARNING - Flash write address is not aligned to the recommeded 32 bytes')
|
||||
do_write = False
|
||||
for address, argfile in args.addr_filename:
|
||||
if address % esp.FLASH_ENCRYPTED_WRITE_ALIGN:
|
||||
print("File %s address 0x%x is not %d byte aligned, can't flash encrypted" %
|
||||
(argfile.name, address, esp.FLASH_ENCRYPTED_WRITE_ALIGN))
|
||||
do_write = False
|
||||
|
||||
if not do_write and not args.ignore_flash_encryption_efuse_setting:
|
||||
raise FatalError("Incorrect efuse setting: aborting flash write")
|
||||
raise FatalError("Can't perform encrypted flash write, consult Flash Encryption documentation for more information")
|
||||
|
||||
# verify file sizes fit in flash
|
||||
if args.flash_size != 'keep': # TODO: check this even with 'keep'
|
||||
@ -2514,7 +2598,7 @@ def write_flash(esp, args):
|
||||
for address, argfile in args.addr_filename:
|
||||
if args.no_stub:
|
||||
print('Erasing flash...')
|
||||
image = pad_to(argfile.read(), 32 if args.encrypt else 4)
|
||||
image = pad_to(argfile.read(), esp.FLASH_ENCRYPTED_WRITE_ALIGN if args.encrypt else 4)
|
||||
if len(image) == 0:
|
||||
print('WARNING: File %s is empty' % argfile.name)
|
||||
continue
|
||||
@ -2810,6 +2894,7 @@ def main(custom_commandline=None):
|
||||
|
||||
parser.add_argument('--chip', '-c',
|
||||
help='Target chip type',
|
||||
type=lambda c: c.lower().replace('-', ''), # support ESP32-S2, etc.
|
||||
choices=['auto', 'esp8266', 'esp32', 'esp32s2'],
|
||||
default=os.environ.get('ESPTOOL_CHIP', 'auto'))
|
||||
|
||||
@ -3354,67 +3439,68 @@ sWE7u6I9uaJtLm2fX9L65ZJW/2Veq9rlpe3FZWfnys/nntvss3B0/hn7HkLeXCEFBpDrASTDN7np3nxr
|
||||
anYncIInj4LL4q+4WyDyigN5h7E7aat03Cd3GrHp61vKySRu/dj04/8DUJQftQ==\
|
||||
""")))
|
||||
ESP32ROM.STUB_CODE = eval(zlib.decompress(base64.b64decode(b"""
|
||||
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\
|
||||
""")))
|
||||
ESP32S2ROM.STUB_CODE = eval(zlib.decompress(base64.b64decode(b"""
|
||||
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\
|
||||
mQ6gPNFFkn39LwZ+5OE=\
|
||||
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\
|
||||
""")))
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user