Update: 更新esptool ( version: 4.7.0 )
This commit is contained in:
@@ -11,6 +11,8 @@ import sys
|
||||
import time
|
||||
import zlib
|
||||
|
||||
from intelhex import IntelHex
|
||||
|
||||
from bin_image import ELFFile, ImageSegment, LoadFirmwareImage
|
||||
from bin_image import (
|
||||
ESP8266ROMFirmwareImage,
|
||||
@@ -25,6 +27,7 @@ from loader import (
|
||||
timeout_per_mb,
|
||||
)
|
||||
from targets import CHIP_DEFS, CHIP_LIST, ROM_LIST
|
||||
from uf2_writer import UF2Writer
|
||||
from util import (
|
||||
FatalError,
|
||||
NotImplementedInROMError,
|
||||
@@ -96,7 +99,7 @@ def detect_chip(
|
||||
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", "ESP32S2")
|
||||
n for n in ROM_LIST if n.CHIP_NAME not in ("ESP8266", "ESP32", "ESP32-S2")
|
||||
]:
|
||||
# cmd not supported on ESP8266 and ESP32 + ESP32-S2 doesn't return chip_id
|
||||
if chip_id == cls.IMAGE_CHIP_ID:
|
||||
@@ -466,7 +469,7 @@ def write_flash(esp, args):
|
||||
flash_end = flash_size_bytes(
|
||||
detect_flash_size(esp) if args.flash_size == "keep" else args.flash_size
|
||||
)
|
||||
if flash_end is not None: # Secure download mode
|
||||
if flash_end is not None: # Not in secure download mode
|
||||
for address, argfile in args.addr_filename:
|
||||
argfile.seek(0, os.SEEK_END)
|
||||
if address + argfile.tell() > flash_end:
|
||||
@@ -979,6 +982,8 @@ def elf2image(args):
|
||||
args.chip = "esp8266"
|
||||
|
||||
print("Creating {} image...".format(args.chip))
|
||||
if args.ram_only_header:
|
||||
print("ROM segments hidden - only RAM segments are visible to the ROM loader!")
|
||||
|
||||
if args.chip != "esp8266":
|
||||
image = CHIP_DEFS[args.chip].BOOTLOADER_IMAGE()
|
||||
@@ -989,6 +994,7 @@ def elf2image(args):
|
||||
image.min_rev = args.min_rev
|
||||
image.min_rev_full = args.min_rev_full
|
||||
image.max_rev_full = args.max_rev_full
|
||||
image.ram_only_header = args.ram_only_header
|
||||
image.append_digest = args.append_digest
|
||||
elif args.version == "1": # ESP8266
|
||||
image = ESP8266ROMFirmwareImage()
|
||||
@@ -1106,9 +1112,9 @@ def read_flash(esp, args):
|
||||
|
||||
def flash_progress(progress, length):
|
||||
msg = "%d (%d %%)" % (progress, progress * 100.0 / length)
|
||||
# padding = "\b" * len(msg)
|
||||
# if progress == length:
|
||||
padding = "\n"
|
||||
padding = "\b" * len(msg)
|
||||
if progress == length:
|
||||
padding = "\n"
|
||||
sys.stdout.write(msg + padding)
|
||||
sys.stdout.flush()
|
||||
|
||||
@@ -1180,15 +1186,95 @@ def write_flash_status(esp, args):
|
||||
print(("After flash status: " + fmt) % esp.read_status(args.bytes))
|
||||
|
||||
|
||||
# The following mapping was taken from the ROM code
|
||||
# This mapping is same across all targets in the ROM
|
||||
SECURITY_INFO_FLAG_MAP = {
|
||||
"SECURE_BOOT_EN": (1 << 0),
|
||||
"SECURE_BOOT_AGGRESSIVE_REVOKE": (1 << 1),
|
||||
"SECURE_DOWNLOAD_ENABLE": (1 << 2),
|
||||
"SECURE_BOOT_KEY_REVOKE0": (1 << 3),
|
||||
"SECURE_BOOT_KEY_REVOKE1": (1 << 4),
|
||||
"SECURE_BOOT_KEY_REVOKE2": (1 << 5),
|
||||
"SOFT_DIS_JTAG": (1 << 6),
|
||||
"HARD_DIS_JTAG": (1 << 7),
|
||||
"DIS_USB": (1 << 8),
|
||||
"DIS_DOWNLOAD_DCACHE": (1 << 9),
|
||||
"DIS_DOWNLOAD_ICACHE": (1 << 10),
|
||||
}
|
||||
|
||||
|
||||
# Get the status of respective security flag
|
||||
def get_security_flag_status(flag_name, flags_value):
|
||||
try:
|
||||
return (flags_value & SECURITY_INFO_FLAG_MAP[flag_name]) != 0
|
||||
except KeyError:
|
||||
raise ValueError(f"Invalid flag name: {flag_name}")
|
||||
|
||||
|
||||
def get_security_info(esp, args):
|
||||
si = esp.get_security_info()
|
||||
# TODO: better display
|
||||
print()
|
||||
title = "Security Information:"
|
||||
print(title)
|
||||
print("=" * len(title))
|
||||
print("Flags: {:#010x} ({})".format(si["flags"], bin(si["flags"])))
|
||||
print("Flash_Crypt_Cnt: {:#x}".format(si["flash_crypt_cnt"]))
|
||||
print("Key_Purposes: {}".format(si["key_purposes"]))
|
||||
print("Key Purposes: {}".format(si["key_purposes"]))
|
||||
if si["chip_id"] is not None and si["api_version"] is not None:
|
||||
print("Chip_ID: {}".format(si["chip_id"]))
|
||||
print("Api_Version: {}".format(si["api_version"]))
|
||||
print("Chip ID: {}".format(si["chip_id"]))
|
||||
print("API Version: {}".format(si["api_version"]))
|
||||
|
||||
flags = si["flags"]
|
||||
|
||||
if get_security_flag_status("SECURE_BOOT_EN", flags):
|
||||
print("Secure Boot: Enabled")
|
||||
if get_security_flag_status("SECURE_BOOT_AGGRESSIVE_REVOKE", flags):
|
||||
print("Secure Boot Aggressive key revocation: Enabled")
|
||||
|
||||
revoked_keys = []
|
||||
for i, key in enumerate(
|
||||
[
|
||||
"SECURE_BOOT_KEY_REVOKE0",
|
||||
"SECURE_BOOT_KEY_REVOKE1",
|
||||
"SECURE_BOOT_KEY_REVOKE2",
|
||||
]
|
||||
):
|
||||
if get_security_flag_status(key, flags):
|
||||
revoked_keys.append(i)
|
||||
|
||||
if len(revoked_keys) > 0:
|
||||
print("Secure Boot Key Revocation Status:\n")
|
||||
for i in revoked_keys:
|
||||
print(f"\tSecure Boot Key{i} is Revoked\n")
|
||||
|
||||
else:
|
||||
print("Secure Boot: Disabled")
|
||||
|
||||
flash_crypt_cnt = bin(si["flash_crypt_cnt"])
|
||||
if (flash_crypt_cnt.count("1") % 2) != 0:
|
||||
print("Flash Encryption: Enabled")
|
||||
else:
|
||||
print("Flash Encryption: Disabled")
|
||||
|
||||
CRYPT_CNT_STRING = "SPI Boot Crypt Count (SPI_BOOT_CRYPT_CNT)"
|
||||
if esp.CHIP_NAME == "esp32":
|
||||
CRYPT_CNT_STRING = "Flash Crypt Count (FLASH_CRYPT_CNT)"
|
||||
|
||||
print(f"{CRYPT_CNT_STRING}: {si['flash_crypt_cnt']:#x}")
|
||||
|
||||
if get_security_flag_status("DIS_DOWNLOAD_DCACHE", flags):
|
||||
print("Dcache in UART download mode: Disabled")
|
||||
|
||||
if get_security_flag_status("DIS_DOWNLOAD_ICACHE", flags):
|
||||
print("Icache in UART download mode: Disabled")
|
||||
|
||||
hard_dis_jtag = get_security_flag_status("HARD_DIS_JTAG", flags)
|
||||
soft_dis_jtag = get_security_flag_status("SOFT_DIS_JTAG", flags)
|
||||
if hard_dis_jtag:
|
||||
print("JTAG: Permenantly Disabled")
|
||||
elif soft_dis_jtag:
|
||||
print("JTAG: Software Access Disabled")
|
||||
if get_security_flag_status("DIS_USB", flags):
|
||||
print("USB Access: Disabled")
|
||||
|
||||
|
||||
def merge_bin(args):
|
||||
@@ -1198,9 +1284,9 @@ def merge_bin(args):
|
||||
msg = (
|
||||
"Please specify the chip argument"
|
||||
if args.chip == "auto"
|
||||
else "Invalid chip choice: '{}'".format(args.chip)
|
||||
else f"Invalid chip choice: '{args.chip}'"
|
||||
)
|
||||
msg = msg + " (choose from {})".format(", ".join(CHIP_LIST))
|
||||
msg = f"{msg} (choose from {', '.join(CHIP_LIST)})"
|
||||
raise FatalError(msg)
|
||||
|
||||
# sort the files by offset.
|
||||
@@ -1211,31 +1297,57 @@ def merge_bin(args):
|
||||
first_addr = input_files[0][0]
|
||||
if first_addr < args.target_offset:
|
||||
raise FatalError(
|
||||
"Output file target offset is 0x%x. Input file offset 0x%x is before this."
|
||||
% (args.target_offset, first_addr)
|
||||
f"Output file target offset is {args.target_offset:#x}. "
|
||||
f"Input file offset {first_addr:#x} is before this."
|
||||
)
|
||||
|
||||
if args.format != "raw":
|
||||
raise FatalError(
|
||||
"This version of esptool only supports the 'raw' output format"
|
||||
if args.format == "uf2":
|
||||
with UF2Writer(
|
||||
chip_class.UF2_FAMILY_ID,
|
||||
args.output,
|
||||
args.chunk_size,
|
||||
md5_enabled=not args.md5_disable,
|
||||
) as writer:
|
||||
for addr, argfile in input_files:
|
||||
print(f"Adding {argfile.name} at {addr:#x}")
|
||||
image = argfile.read()
|
||||
image = _update_image_flash_params(chip_class, addr, args, image)
|
||||
writer.add_file(addr, image)
|
||||
print(
|
||||
f"Wrote {os.path.getsize(args.output):#x} bytes to file {args.output}, "
|
||||
f"ready to be flashed with any ESP USB Bridge"
|
||||
)
|
||||
|
||||
with open(args.output, "wb") as of:
|
||||
elif args.format == "raw":
|
||||
with open(args.output, "wb") as of:
|
||||
|
||||
def pad_to(flash_offs):
|
||||
# account for output file offset if there is any
|
||||
of.write(b"\xFF" * (flash_offs - args.target_offset - of.tell()))
|
||||
def pad_to(flash_offs):
|
||||
# account for output file offset if there is any
|
||||
of.write(b"\xFF" * (flash_offs - args.target_offset - of.tell()))
|
||||
|
||||
for addr, argfile in input_files:
|
||||
pad_to(addr)
|
||||
image = argfile.read()
|
||||
image = _update_image_flash_params(chip_class, addr, args, image)
|
||||
of.write(image)
|
||||
if args.fill_flash_size:
|
||||
pad_to(flash_size_bytes(args.fill_flash_size))
|
||||
print(
|
||||
f"Wrote {of.tell():#x} bytes to file {args.output}, "
|
||||
f"ready to flash to offset {args.target_offset:#x}"
|
||||
)
|
||||
elif args.format == "hex":
|
||||
out = IntelHex()
|
||||
for addr, argfile in input_files:
|
||||
pad_to(addr)
|
||||
ihex = IntelHex()
|
||||
image = argfile.read()
|
||||
image = _update_image_flash_params(chip_class, addr, args, image)
|
||||
of.write(image)
|
||||
if args.fill_flash_size:
|
||||
pad_to(flash_size_bytes(args.fill_flash_size))
|
||||
ihex.frombytes(image, addr)
|
||||
out.merge(ihex)
|
||||
out.write_hex_file(args.output)
|
||||
print(
|
||||
"Wrote 0x%x bytes to file %s, ready to flash to offset 0x%x"
|
||||
% (of.tell(), args.output, args.target_offset)
|
||||
f"Wrote {os.path.getsize(args.output):#x} bytes to file {args.output}, "
|
||||
f"ready to flash to offset {args.target_offset:#x}"
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user