summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2022-06-22 16:51:34 -0700
committerH. Peter Anvin <hpa@zytor.com>2022-06-22 16:51:34 -0700
commit378d46cb8fd3472d19f348c28c6ac3408d98dc2f (patch)
tree3cf0dbba1539f6813b7b5131a354764884ff72bf
parentb746a57a9f1faa13fd6853927e657c39dc32f23d (diff)
downloadblinktest-378d46cb8fd3472d19f348c28c6ac3408d98dc2f.tar.gz
blinktest-378d46cb8fd3472d19f348c28c6ac3408d98dc2f.tar.xz
blinktest-378d46cb8fd3472d19f348c28c6ac3408d98dc2f.zip
flashesp: include all ESP32 flash data in .fw; script to flash
Add all ESP32 flash data (partition table, boot loader, and OTA control partition) in the .fw image; this data is extremely compressible so it adds very little to the size. Add a Perl script (esp32/flashesp.pl) to flash the .fw image to the ESP using esptool.py over a serial port or USB.
-rw-r--r--common/fwimg.h5
-rw-r--r--esp32/boot_app0.binbin0 -> 8192 bytes
-rw-r--r--esp32/esptool.opt1
-rwxr-xr-xesp32/flashesp.pl182
-rw-r--r--esp32/output/max80.ino.binbin774352 -> 774352 bytes
-rw-r--r--fpga/Makefile21
-rw-r--r--fpga/max80.qpf4
-rw-r--r--fpga/output/v1.fwbin736390 -> 746390 bytes
-rw-r--r--fpga/output/v1.jicbin16777443 -> 16777443 bytes
-rw-r--r--fpga/output/v1.rbf.gzbin161042 -> 161040 bytes
-rw-r--r--fpga/output/v1.rpd.gzbin218438 -> 177361 bytes
-rw-r--r--fpga/output/v1.sofbin509096 -> 509096 bytes
-rw-r--r--fpga/output/v1.svf.gzbin183083 -> 183089 bytes
-rw-r--r--fpga/output/v1.xsvf.gzbin165418 -> 165422 bytes
-rw-r--r--fpga/output/v2.fwbin736823 -> 746828 bytes
-rw-r--r--fpga/output/v2.jicbin16777443 -> 16777443 bytes
-rw-r--r--fpga/output/v2.rbf.gzbin161582 -> 161588 bytes
-rw-r--r--fpga/output/v2.rpd.gzbin217855 -> 177079 bytes
-rw-r--r--fpga/output/v2.sofbin509096 -> 509096 bytes
-rw-r--r--fpga/output/v2.svf.gzbin184081 -> 184085 bytes
-rw-r--r--fpga/output/v2.xsvf.gzbin165771 -> 165777 bytes
-rwxr-xr-xtools/mkfwimage.pl14
22 files changed, 216 insertions, 11 deletions
diff --git a/common/fwimg.h b/common/fwimg.h
index 38f0653..2c5f985 100644
--- a/common/fwimg.h
+++ b/common/fwimg.h
@@ -26,7 +26,10 @@ enum fw_data_type {
FDT_TARGET, /* Subsystem string (must match) */
FDT_NOTE, /* Version: XXXXX or similar */
FDT_ESP_OTA, /* ESP32 OTA image */
- FDT_FPGA_INIT /* FPGA bitstream for update */
+ FDT_FPGA_INIT, /* FPGA bitstream for update */
+ FDT_ESP_PART, /* ESP32 partition table */
+ FDT_ESP_SYS, /* ESP32 boot loader, OTA control, etc */
+ FDT_ESP_TOOL /* esptool.py options for serial flashing */
};
enum fw_data_flags {
FDF_OPTIONAL = 0x0001 /* Ignore if chunk data type unknown */
diff --git a/esp32/boot_app0.bin b/esp32/boot_app0.bin
new file mode 100644
index 0000000..13562ca
--- /dev/null
+++ b/esp32/boot_app0.bin
Binary files differ
diff --git a/esp32/esptool.opt b/esp32/esptool.opt
new file mode 100644
index 0000000..2a63982
--- /dev/null
+++ b/esp32/esptool.opt
@@ -0,0 +1 @@
+baud 921600 chip esp32s2 flash_mode dio flash_freq 80m flash_size 4MB
diff --git a/esp32/flashesp.pl b/esp32/flashesp.pl
new file mode 100755
index 0000000..47dbc32
--- /dev/null
+++ b/esp32/flashesp.pl
@@ -0,0 +1,182 @@
+#!/usr/bin/perl
+
+use strict;
+use integer;
+use PerlIO::gzip;
+use File::Temp;
+use File::Spec;
+
+my $esptool = ($^O eq 'MSWin32') ? 'esptool.exe' : 'esptool.py';
+$esptool = $ENV{'ESPTOOL'} || $esptool;
+
+my $FW_MAGIC = 0x7a07fbd6;
+
+my %datatypes = (
+ 'end' => 0, # End of data
+ 'data' => 1, # FPGA flash data
+ 'target' => 2, # Firmware target string
+ 'note' => 3, # Informative string
+ 'espota' => 4, # ESP32 OTA image
+ 'fpgainit' => 5, # FPGA bypass (transient) image during update
+ 'esppart' => 6, # ESP32 partition table
+ 'espsys' => 7, # ESP32 boot loader, OTA control partition...
+ 'esptool' => 8 # esptool.py options for flashing
+ );
+my @type;
+foreach my $t (keys(%datatypes)) {
+ $type[$datatypes{$t}] = $t;
+}
+
+my $FDF_OPTIONAL = 0x0001;
+
+my $STRING_MAX_LEN = 4095;
+
+sub getint($) {
+ my($s) = @_;
+
+ return undef
+ unless ($s =~ /^(([1-9][0-9]+)|(0(x[0-9a-f]+|[0-7]*)))([kmgtpe]?)$/i);
+
+ my $o = oct($3) + $2;
+ my $p = lc($5);
+
+ if ($p eq 'k') {
+ $o <<= 10;
+ } elsif ($p eq 'm') {
+ $o <<= 20;
+ } elsif ($p eq 'g') {
+ $o <<= 30;
+ } elsif ($p eq 't') {
+ $o <<= 40;
+ } elsif ($p eq 'p') {
+ $o <<= 50;
+ } elsif ($p eq 'e') {
+ $o <<= 60;
+ }
+ return $o;
+}
+
+sub filelen($) {
+ my($f) = @_;
+ my @s = stat($f);
+
+ return $s[7];
+}
+
+sub unquote_cmd($) {
+ my($s) = @_;
+ my @a;
+
+ $s =~ s/[\r\n]+/ /g;
+ while ($s =~ /^\s*(?:\"((?:[^\"]+|\"\")*)\"|(\S+))(\s.*)?$/) {
+ push(@a, $1.$2);
+ $s = $3;
+ }
+
+ return @a;
+}
+
+my @args = @ARGV;
+my $file = shift(@args);
+
+if (!defined($file)) {
+ die "Usage: $0 fwfile [esptool options...]\n";
+}
+
+open(my $fw, '<:gzip', $file)
+ or die "$0: $file: $!\n";
+
+my @chunks = ();
+
+my $err = 0;
+
+my $hdr;
+while (read($fw, $hdr, 16) == 16) {
+ # magic type flags data_len addr
+ my @h = unpack('VvvVV', $hdr);
+ my $c = { 'hdr' => $hdr, 'magic' => $h[0], 'type' => $h[1],
+ 'flags' => $h[2], 'len' => $h[3], 'addr' => $h[4] };
+ if ($c->{'magic'} != $FW_MAGIC) {
+ print STDERR "$0: $file: bad chunk magic\n";
+ $err = 1;
+ last;
+ }
+
+ my $t = $type[$c->{'type'}];
+ last if ($t eq 'end'); # End of stream
+
+ my $d;
+ if (read($fw, $d, $c->{'len'}) != $c->{'len'}) {
+ print STDERR "$0: $file: short chunk read\n";
+ $err = 1;
+ last;
+ }
+ $c->{'data'} = $d;
+
+ push(@chunks, $c);
+}
+
+close($fw);
+exit $err if ($err);
+
+my $td = File::Temp->newdir(CLEANUP => 1);
+
+my @espfiles = ();
+my %espopt = ('before' => 'default_reset', 'after' => 'hard_reset',
+ 'baud' => 115200, 'port' => undef, 'chip' => undef,
+ 'flash_mode' => undef, 'flash_freq' => undef,
+ 'flash_size' => undef);
+
+my $nc = 0;
+foreach my $c ( @chunks ) {
+ my $t = $type[$c->{'type'}];
+ if ($t eq 'esptool') {
+ my $s = $c->{'data'};
+ $s =~ s/[\r\n]+/ /g;
+ while ($s =~ /^\s*(\S+)\s+(\S+)(.*)/) {
+ $espopt{$1} = $2;
+ $s = $3;
+ }
+ } elsif ($t =~ /^esp/ && $c->{'addr'}) {
+ my $addr = sprintf('%x', $c->{'addr'});
+ my $tff = File::Spec->catfile($td, $t.$nc.'_'.$addr.'.bin');
+ open(my $tf, '>', $tff) or die "$0: $tff: $!\n";
+ print $tf $c->{'data'};
+ close($tf);
+ push(@espfiles, '0x'.$addr, $tff);
+ }
+ $nc++;
+}
+
+foreach my $e (keys %espopt) {
+ my $ev = $ENV{"ESP\U$e"};
+ if (defined($ev)) {
+ $espopt{$e} = $ev;
+ }
+}
+
+my @espcmd = unquote_cmd($esptool);
+foreach my $o (sort grep (!/^flash_/, keys %espopt)) {
+ if (defined($espopt{$o})) {
+ push(@espcmd, "--$o", $espopt{$o});
+ }
+}
+push(@espcmd, @args);
+push(@espcmd, 'write_flash', '-z');
+foreach my $o (sort grep (/^flash_/, keys %espopt)) {
+ if (defined($espopt{$o})) {
+ push(@espcmd, "--$o", $espopt{$o});
+ }
+}
+push(@espcmd, @espfiles);
+
+if (defined($ENV{'VERBOSE'})) {
+ print STDERR join(' ', @espcmd), "\n";
+}
+
+$err = system(@espcmd);
+if ($err == -1) {
+ print STDERR "$0: $espcmd[0]: $!\n";
+}
+
+exit !!$err;
diff --git a/esp32/output/max80.ino.bin b/esp32/output/max80.ino.bin
index 3d891d2..9728a2d 100644
--- a/esp32/output/max80.ino.bin
+++ b/esp32/output/max80.ino.bin
Binary files differ
diff --git a/fpga/Makefile b/fpga/Makefile
index 428e636..ec9a3bf 100644
--- a/fpga/Makefile
+++ b/fpga/Makefile
@@ -45,9 +45,18 @@ allout = $(foreach o,$(alltarg),$(outdir)/$(1).$(o))
sram_src = ../rv32/
-DRAM_ADDR := 0x100000
-DRAM_IMAGE := ../rv32/dram.bin
-ESP_IMAGE := ../esp32/output/max80.ino.bin
+DRAM_ADDR := 0x100000
+DRAM_IMAGE := ../rv32/dram.bin
+
+ESP_ADDR := 0x10000
+ESP_IMAGE := ../esp32/output/max80.ino.bin
+ESP_BOOT_ADDR := 0x1000
+ESP_BOOT_IMAGE := ../esp32/output/max80.ino.bootloader.bin
+ESP_PART_ADDR := 0x8000
+ESP_PART_IMAGE := ../esp32/output/max80.ino.partitions.bin
+ESP_OTACTL_ADDR := 0xe000
+ESP_OTACTL_IMAGE := ../esp32/boot_app0.bin
+ESP_TOOL_OPT := ../esp32/esptool.opt
IDCODE := 0x020f20dd # JTAG IDCODE of FPGA
@@ -181,7 +190,11 @@ $(outdir)/%.fw: $(outdir)/%.rpf $(outdir)/bypass.rbf \
-type fpgainit -addr $(IDCODE) -optional -file $(outdir)/bypass.rbf \
-type data -addr 0 -file $< \
-type data -addr $(DRAM_ADDR) -file $(DRAM_IMAGE) \
- -type espota -file $(ESP_IMAGE) \
+ -type esptool -optional -file $(ESP_TOOL_OPT) \
+ -type espota -addr $(ESP_ADDR) -file $(ESP_IMAGE) \
+ -type esppart -optional -addr $(ESP_PART_ADDR) -file $(ESP_PART_IMAGE) \
+ -type espsys -optional -addr $(ESP_BOOT_ADDR) -file $(ESP_BOOT_IMAGE) \
+ -type espsys -optional -addr $(ESP_OTACTL_ADDR) -file $(ESP_OTACTL_IMAGE) \
| $(GZIP) -9 > $@
$(outdir)/%.update.svf: ./scripts/flashsvf.pl \
diff --git a/fpga/max80.qpf b/fpga/max80.qpf
index 5ff27f8..e5846a5 100644
--- a/fpga/max80.qpf
+++ b/fpga/max80.qpf
@@ -19,12 +19,12 @@
#
# Quartus Prime
# Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
-# Date created = 12:23:20 June 22, 2022
+# Date created = 15:52:01 June 22, 2022
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "21.1"
-DATE = "12:23:20 June 22, 2022"
+DATE = "15:52:01 June 22, 2022"
# Revisions
diff --git a/fpga/output/v1.fw b/fpga/output/v1.fw
index 1463093..df65004 100644
--- a/fpga/output/v1.fw
+++ b/fpga/output/v1.fw
Binary files differ
diff --git a/fpga/output/v1.jic b/fpga/output/v1.jic
index bd213c6..0a765cf 100644
--- a/fpga/output/v1.jic
+++ b/fpga/output/v1.jic
Binary files differ
diff --git a/fpga/output/v1.rbf.gz b/fpga/output/v1.rbf.gz
index 0895054..644889f 100644
--- a/fpga/output/v1.rbf.gz
+++ b/fpga/output/v1.rbf.gz
Binary files differ
diff --git a/fpga/output/v1.rpd.gz b/fpga/output/v1.rpd.gz
index 279cbc8..0b199f4 100644
--- a/fpga/output/v1.rpd.gz
+++ b/fpga/output/v1.rpd.gz
Binary files differ
diff --git a/fpga/output/v1.sof b/fpga/output/v1.sof
index 13992cf..769a9b1 100644
--- a/fpga/output/v1.sof
+++ b/fpga/output/v1.sof
Binary files differ
diff --git a/fpga/output/v1.svf.gz b/fpga/output/v1.svf.gz
index b98e822..fa86ab4 100644
--- a/fpga/output/v1.svf.gz
+++ b/fpga/output/v1.svf.gz
Binary files differ
diff --git a/fpga/output/v1.xsvf.gz b/fpga/output/v1.xsvf.gz
index da2e6e2..546d894 100644
--- a/fpga/output/v1.xsvf.gz
+++ b/fpga/output/v1.xsvf.gz
Binary files differ
diff --git a/fpga/output/v2.fw b/fpga/output/v2.fw
index f2e98ec..6c23da7 100644
--- a/fpga/output/v2.fw
+++ b/fpga/output/v2.fw
Binary files differ
diff --git a/fpga/output/v2.jic b/fpga/output/v2.jic
index 564bff9..1935f14 100644
--- a/fpga/output/v2.jic
+++ b/fpga/output/v2.jic
Binary files differ
diff --git a/fpga/output/v2.rbf.gz b/fpga/output/v2.rbf.gz
index 03ec314..dc96ef9 100644
--- a/fpga/output/v2.rbf.gz
+++ b/fpga/output/v2.rbf.gz
Binary files differ
diff --git a/fpga/output/v2.rpd.gz b/fpga/output/v2.rpd.gz
index 440f599..86284f9 100644
--- a/fpga/output/v2.rpd.gz
+++ b/fpga/output/v2.rpd.gz
Binary files differ
diff --git a/fpga/output/v2.sof b/fpga/output/v2.sof
index 4bb83e2..04b0da2 100644
--- a/fpga/output/v2.sof
+++ b/fpga/output/v2.sof
Binary files differ
diff --git a/fpga/output/v2.svf.gz b/fpga/output/v2.svf.gz
index d71cf3c..c65d083 100644
--- a/fpga/output/v2.svf.gz
+++ b/fpga/output/v2.svf.gz
Binary files differ
diff --git a/fpga/output/v2.xsvf.gz b/fpga/output/v2.xsvf.gz
index a971d07..3edf618 100644
--- a/fpga/output/v2.xsvf.gz
+++ b/fpga/output/v2.xsvf.gz
Binary files differ
diff --git a/tools/mkfwimage.pl b/tools/mkfwimage.pl
index 4ec974d..088f638 100755
--- a/tools/mkfwimage.pl
+++ b/tools/mkfwimage.pl
@@ -2,7 +2,6 @@
use strict;
use integer;
-use Digest::MD5;
my $FW_MAGIC = 0x7a07fbd6;
@@ -12,8 +11,15 @@ my %datatypes = (
'target' => 2, # Firmware target string
'note' => 3, # Informative string
'espota' => 4, # ESP32 OTA image
- 'fpgainit' => 5 # FPGA bypass (transient) image during update
+ 'fpgainit' => 5, # FPGA bypass (transient) image during update
+ 'esppart' => 6, # ESP32 partition table
+ 'espsys' => 7, # ESP32 boot loader, OTA control partition...
+ 'esptool' => 8 # esptool.py options for flashing
);
+my @type;
+foreach my $t (keys(%datatypes)) {
+ $type[$datatypes{$t}] = $t;
+}
my $FDF_OPTIONAL = 0x0001;
@@ -55,8 +61,8 @@ sub output_chunk($$$) {
print $out pack("VvvVV", $FW_MAGIC,
$options->{'type'}, $options->{'flags'},
length($data), $options->{'addr'});
- printf STDERR "chunk: type %u flags 0x%x length %u addr 0x%x\n",
- $options->{'type'}, $options->{'flags'},
+ printf STDERR "chunk: type %s (%u) flags 0x%x length %u addr 0x%x\n",
+ $type[$options->{'type'}], $options->{'type'}, $options->{'flags'},
length($data), $options->{'addr'};
print $out $data;
}