Skip to content

Commit

Permalink
Allow to change flash parameters only when no SHA256 digest is appended
Browse files Browse the repository at this point in the history
Partial fix for espressif/esp-idf#8798
  • Loading branch information
dobairoland committed May 11, 2022
1 parent 2d784ae commit 13d9202
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 5 deletions.
34 changes: 31 additions & 3 deletions esptool/cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,16 +260,44 @@ def _update_image_flash_params(esp, address, args, image):
)
return image

# After the 8-byte header comes the extended header for chips others than ESP8266.
# The 15th byte of the extended header indicates if the image is protected by
# a SHA256 checksum. In that case we should not modify the header because
# the checksum check would fail.
sha_implies_keep = args.chip != "esp8266" and image[8 + 15] == 1

def print_keep_warning(arg_to_keep, arg_used):
print(
"Warning: Image file at {addr} is protected with a hash checksum, "
"so not changing the flash {arg} setting. "
"Use the --flash_{arg}=keep option instead of --flash_{arg}={arg_orig} "
"in order to remove this warning".format(
addr=hex(address), arg=arg_to_keep, arg_orig=arg_used
)
)

if args.flash_mode != "keep":
flash_mode = FLASH_MODES[args.flash_mode]
new_flash_mode = FLASH_MODES[args.flash_mode]
if flash_mode != new_flash_mode and sha_implies_keep:
print_keep_warning("mode", args.flash_mode)
else:
flash_mode = new_flash_mode

flash_freq = flash_size_freq & 0x0F
if args.flash_freq != "keep":
flash_freq = esp.parse_flash_freq_arg(args.flash_freq)
new_flash_freq = esp.parse_flash_freq_arg(args.flash_freq)
if flash_freq != new_flash_freq and sha_implies_keep:
print_keep_warning("frequency", args.flash_freq)
else:
flash_freq = new_flash_freq

flash_size = flash_size_freq & 0xF0
if args.flash_size != "keep":
flash_size = esp.parse_flash_size_arg(args.flash_size)
new_flash_size = esp.parse_flash_size_arg(args.flash_size)
if flash_size != new_flash_size and sha_implies_keep:
print_keep_warning("size", args.flash_size)
else:
flash_size = new_flash_size

flash_params = struct.pack(b"BB", flash_mode, flash_size + flash_freq)
if flash_params != image[2:4]:
Expand Down
19 changes: 17 additions & 2 deletions test/test_esptool.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,9 +759,17 @@ def test_detect_size_changes_size(self):
)
readback = self.readback(self.flash_offset, 8)
self.assertEqual(self.header[:3], readback[:3]) # first 3 bytes unchanged
self.assertNotEqual(self.header[3], readback[3]) # size_freq byte changed
if chip in ["esp8266", "esp32"]:
self.assertNotEqual(self.header[3], readback[3]) # size_freq byte changed
else:
# Not changed because protected by SHA256 digest
self.assertEqual(self.header[3], readback[3]) # size_freq byte unchanged
self.assertEqual(self.header[4:], readback[4:]) # rest unchanged

@unittest.skipUnless(
chip in ["esp8266", "esp32"],
"Bootloader header needs to be modifiable - without sha256",
)
def test_explicit_set_size_freq_mode(self):
self.run_esptool(
"write_flash -fs 2MB -fm dout -ff 80m 0x%x %s"
Expand Down Expand Up @@ -855,7 +863,14 @@ def test_flash_header_rewrite(self):
output = self.run_esptool(
"write_flash -fm dout -ff 20m 0x%x %s" % (self.BL_OFFSET, bl_image)
)
self.assertIn("Flash params set to", output)
if chip in ["esp8266", "esp32"]:
# There is no SHA256 digest so the header can be changed - ESP8266 doesn't
# support this; The test image for ESP32 just doesn't have it.
self.assertIn("Flash params set to", output)
else:
self.assertNotIn("Flash params set to", output)
self.assertIn("not changing the flash mode setting", output)
self.assertIn("not changing the flash frequency setting", output)

def test_flash_header_no_magic_no_rewrite(self):
# first image doesn't start with magic byte, second image does
Expand Down

0 comments on commit 13d9202

Please sign in to comment.