def load_ram(esp, args):
    if(esp.CHIP_NAME == 'ESP32'):
        image = esptool.LoadFirmwareImage("esp32", args.filename)
    else:
        image = esptool.LoadFirmwareImage("esp8266", args.filename)

    if(DEBUG): print('RAM boot...')
    for seg in image.segments:
        offset = seg.addr
        data = seg.data
        size = seg.file_offs

        if(DEBUG): print('Downloading %d bytes at %08x...' % (size, offset))
        sys.stdout.flush()
        esp.mem_begin(size, esptool.div_roundup(size, esp.ESP_RAM_BLOCK), esp.ESP_RAM_BLOCK, offset)

        seq = 0
        while len(data) > 0:
            esp.mem_block(data[0:esp.ESP_RAM_BLOCK], seq)
            data = data[esp.ESP_RAM_BLOCK:]
            seq += 1
        if(DEBUG): print('done!')

    if(DEBUG): print('All segments done, executing at %08x' % image.entrypoint)
    try:
        esp.mem_finish(image.entrypoint)
    except:
        #print "error but ignore"
        pass
Beispiel #2
0
 def test_elf_section_header_not_at_end(self):
     self.run_elf2image("esp8266", self.ELF)
     image = esptool.LoadFirmwareImage("esp8266", self.BIN_LOAD)
     self.assertEqual(3, len(image.segments))
     self.assertImageContainsSection(image, self.ELF, ".data")
     self.assertImageContainsSection(image, self.ELF, ".text")
     self.assertImageContainsSection(image, self.ELF, ".rodata")
Beispiel #3
0
    def _test_elf2image(self, elfpath, binpath):
        try:
            self.run_elf2image("esp8266", elfpath, 2)
            image = esptool.LoadFirmwareImage("esp8266", binpath)
            self.assertEqual(4, len(image.segments))
            self.assertImageContainsSection(image, elfpath, ".data")
            self.assertImageContainsSection(image, elfpath, ".text")
            self.assertImageContainsSection(image, elfpath, ".rodata")
            irom_segment = image.segments[0]
            self.assertEqual(0, irom_segment.addr,
                             "IROM segment 'load address' should be zero")
            with open(elfpath, "rb") as f:
                e = ELFFile(f)
                sh_size = (e.get_section_by_name(".irom0.text").header.sh_size
                           + 15) & ~15
                self.assertEqual(
                    len(irom_segment.data), sh_size,
                    "irom segment (0x%x) should be same size (16 padded) as .irom0.text section (0x%x)"
                    % (len(irom_segment.data), sh_size))

            # check V2 CRC (for ESP8266 SDK bootloader)
            with open(binpath, "rb") as f:
                f.seek(-4, os.SEEK_END)
                image_len = f.tell()
                crc_stored = struct.unpack("<I", f.read(4))[0]
                f.seek(0)
                crc_calc = esptool.esp8266_crc32(f.read(image_len))
                self.assertEqual(crc_stored, crc_calc)

            # test imageinfo doesn't fail
            self.assertImageInfo(binpath)

        finally:
            try_delete(binpath)
Beispiel #4
0
 def _test_elf2image(self, elfpath, binpath, extra_args=[]):
     try:
         self.run_elf2image("esp32", elfpath, extra_args=extra_args)
         image = esptool.LoadFirmwareImage("esp32", binpath)
         self.assertImageInfo(binpath, "esp32")
         return image
     finally:
         try_delete(binpath)
Beispiel #5
0
 def test_loaded_sections(self):
     image = esptool.LoadFirmwareImage("esp8266", self.BIN_LOAD)
     # Adjacent sections are now merged, len(image.segments) should
     # equal 2 (instead of 3).
     self.assertEqual(2, len(image.segments))
     self.assertImageContainsSection(image, self.ELF, ".data")
     self.assertImageContainsSection(image, self.ELF, ".text")
     # Section .rodata is merged in the binary with the previous one,
     # so it won't be found in the binary image.
     self.assertImageDoesNotContainSection(image, self.ELF, ".rodata")
Beispiel #6
0
def load_ram(esp, args, esprftool):
    esprftool._SignalTX.emit('load begin')
    if (esp.CHIP_NAME == 'ESP32'):
        image = esptool.LoadFirmwareImage("esp32", args.filename)
    else:
        image = esptool.LoadFirmwareImage("esp8266", args.filename)

    image_size = os.path.getsize(args.filename)
    send_size = 0

    #print('RAM boot...')
    for seg in image.segments:
        offset = seg.addr
        data = seg.data
        size = seg.file_offs

        sys.stdout.flush()
        esp.mem_begin(size, esptool.div_roundup(size, esp.ESP_RAM_BLOCK),
                      esp.ESP_RAM_BLOCK, offset)

        seq = 0
        while len(data) > 0:
            esp.mem_block(data[0:esp.ESP_RAM_BLOCK], seq)
            data = data[esp.ESP_RAM_BLOCK:]
            seq += 1
            if len(data) < esp.ESP_RAM_BLOCK:
                send_size += len(data)
            else:
                send_size += esp.ESP_RAM_BLOCK
            esprftool._Signalprb.emit(100 * send_size // image_size)
        #print('done!')

    print('All segments done, executing at %08x' % image.entrypoint)
    try:
        esp.mem_finish(image.entrypoint)
    except:
        #print "error but ignore"
        pass
    esprftool._SignalTX.emit('load bin success')
    esp._port.close()
    esprftool._Signalprb.emit(100)
Beispiel #7
0
    def test_binary_patched(self):
        self.run_elf2image("esp32", self.ELF, extra_args=["--elf-sha256-offset", "32"])
        image = esptool.LoadFirmwareImage("esp32", self.BIN)
        rodata_segment = image.segments[0]
        observed_sha256 = rodata_segment.data[0:32]

        sha256 = hashlib.sha256()
        with open(self.ELF, "rb") as f:
            f.seek(0, os.SEEK_END)
            size = f.tell()
            f.seek(0, 0)
            sha256.update(f.read(size))
        expected_sha256 = sha256.digest()

        self.assertSequenceEqual(expected_sha256, observed_sha256)
Beispiel #8
0
    def test_binary_patched(self):
        self.run_elf2image(
            "esp32",
            self.ELF,
            extra_args=["--elf-sha256-offset",
                        "0x%x" % self.SHA_OFFS])
        image = esptool.LoadFirmwareImage("esp32", self.BIN)
        rodata_segment = image.segments[0]
        observed_sha256 = rodata_segment.data[
            self.SHA_OFFS - 0x20:self.SHA_OFFS - 0x20 +
            32]  # subtract 0x20 byte header here

        with open(self.ELF, "rb") as f:
            expected_sha256 = hashlib.sha256(f.read()).digest()

        self.assertSequenceEqual(expected_sha256, observed_sha256)
Beispiel #9
0
def image_info(chip, filename):
    finfo = open("{}.info".format(filename), "wt+")

    image = esptool.LoadFirmwareImage(chip, filename)
    print('Image version: %d' % image.version)
    print('Entry point: %08x' %
          image.entrypoint if image.entrypoint != 0 else 'Entry point not set')
    print("secure_pad: {}".format(image.secure_pad))
    print("flash_mode: {}".format(image.flash_mode))
    print("flash_size_freq: {}".format(image.flash_size_freq))
    finfo.write("0x{:x}\n".format(image.entrypoint))
    finfo.write("{}\n".format(len(image.segments)))
    finfo.write("{} {} {} \n".format(image.secure_pad, image.flash_mode,
                                     image.flash_size_freq))

    print('%d segments' % len(image.segments))
    print()

    idx = 0
    for seg in image.segments:
        idx += 1
        print('Segment %d: %r' % (idx, seg))
        print("  addr=0x{:x} file_offs=0x{:x} include_in_checksum={}\n".format(
            seg.addr, seg.file_offs, seg.include_in_checksum))
        fsegname = "{}.seg{}".format(filename, idx)
        with open(fsegname, "wb+") as file:
            file.write(seg.data)
        finfo.write("{} {} 0x{:x} 0x{:x} {}\n".format(idx, fsegname, seg.addr,
                                                      seg.file_offs,
                                                      seg.include_in_checksum))

    calc_checksum = image.calculate_checksum()
    print('Checksum: %02x (%s)' %
          (image.checksum, 'valid' if image.checksum == calc_checksum else
           'invalid - calculated %02x' % calc_checksum))
    try:
        digest_msg = 'Not appended'
        if image.append_digest:
            is_valid = image.stored_digest == image.calc_digest
            digest_msg = "%s (%s)" % (hexify(
                image.calc_digest).lower(), "valid" if is_valid else "invalid")
            print('Validation Hash: %s' % digest_msg)
    except AttributeError:
        pass  # ESP8266 image has no append_digest field

    finfo.close()
    print("END")
Beispiel #10
0
    def test_binary_patched(self):
        try:
            self.run_elf2image("esp32", self.ELF, extra_args=["--elf-sha256-offset", "0x%x" % self.SHA_OFFS])
            image = esptool.LoadFirmwareImage("esp32", self.BIN)
            rodata_segment = image.segments[0]
            bin_sha256 = rodata_segment.data[self.SHA_OFFS - 0x20: self.SHA_OFFS - 0x20 + 32]  # subtract 0x20 byte header here

            with open(self.ELF, "rb") as f:
                elf_computed_sha256 = hashlib.sha256(f.read()).digest()

            with open(self.BIN, "rb") as f:
                f.seek(self.SHA_OFFS)
                bin_sha256_raw = f.read(len(elf_computed_sha256))

            self.assertSequenceEqual(elf_computed_sha256, bin_sha256)
            self.assertSequenceEqual(elf_computed_sha256, bin_sha256_raw)
        finally:
            try_delete(self.BIN)
Beispiel #11
0
    def _test_elf2image(self, elfpath, binpath):
        try:
            self.run_elf2image("esp8266", elfpath, 2)
            image = esptool.LoadFirmwareImage("esp8266", binpath)
            self.assertEqual(4, len(image.segments))
            self.assertImageContainsSection(image, elfpath, ".data")
            self.assertImageContainsSection(image, elfpath, ".text")
            self.assertImageContainsSection(image, elfpath, ".rodata")
            irom_segment = image.segments[0]
            self.assertEqual(0, irom_segment.addr,
                             "IROM segment 'load address' should be zero")
            with open(elfpath, "rb") as f:
                e = ELFFile(f)
                sh_size = (e.get_section_by_name(".irom0.text").header.sh_size + 3) & ~3
                self.assertEqual(len(irom_segment.data), sh_size, "irom segment (0x%x) should be same size as .irom0.text section (0x%x)" % (len(irom_segment.data), sh_size))

            # test imageinfo doesn't fail
            self.assertImageInfo(binpath)
        finally:
            try_delete(binpath)
Beispiel #12
0
 def test_loaded_sections(self):
     image = esptool.LoadFirmwareImage("esp8266", self.BIN_LOAD)
     self.assertEqual(3, len(image.segments))
     self.assertImageContainsSection(image, self.ELF, ".data")
     self.assertImageContainsSection(image, self.ELF, ".text")
     self.assertImageContainsSection(image, self.ELF, ".rodata")
#!/usr/bin/env python3
# https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map
import sys
# sys.path.append("/home/user/.local/bin/esptool.py") # `which esptool.py`
from esp_elf import XtensaElf, ElfSection
import esptool

if len(sys.argv) == 1:
    print(
        'Usage: ./user_bin_to_elf.py user_app.bin\r\n\r\nThis tool will generate user_app.bin.elf'
    )
    exit(1)

image = esptool.LoadFirmwareImage("", sys.argv[1])
out_elf_file = sys.argv[1] + '.elf'
elf = XtensaElf(out_elf_file, image.entrypoint)

print('Image version: %d' % image.version)
print('Entry point: 0x%08x' %
      image.entrypoint if image.entrypoint != 0 else 'Entry point not set')
print('%d segments' % len(image.segments))
idx = 0
for seg in image.segments:
    idx += 1
    seg_name = ", ".join([
        seg_range[2] for seg_range in image.ROM_LOADER.MEMORY_MAP
        if seg_range[0] <= seg.addr < seg_range[1]
    ])
    print('Segment %d: %r [%s]' % (idx, seg, seg_name))

    elf_section = ElfSection(seg_name, seg.addr, seg.data, seg_name[0] == 'I')