Name
ecoflash — Flash Programming Utility
Synopsis
ecoflash
---help [subcommand]ecoflash
[(1) options] boards ecoflash
[(1) options] info ecoflash
[(1) options] program [[-r] | [--raw]] [[-n] | [--no-erase]] {
file
} [
address
]ecoflash
[(1) options] dump [[-a] | [--append]] {
file
} [
address
] [
length
]ecoflash
[(1) options] erase {
address
} [
length
]ecoflash
[(1) options] write [[-n] | [--no-erase]] [[-o offset
] | [--offset=offset
]] {
file
} {
address
} [
length
]ecoflash
[(1) options] lock {
address
} [
length
]ecoflash
[(1) options] unlock {
address
} [
length
](1)
[[-h] | [--help]]
[--version]
[--dry-run]
[[-q] | [--quiet]]
[[-v] | [--verbose]]
[[-b board
] | [--board=board
]]
[[-g gdb executable
] | [--gdb=gdb executable
]]
[[-o objcopy executable
] | [--objcopy=objcopy executable
]]
[[-t target command
] | [--target=target command
]]
Description
ecoflash is a utility for programming on-board flash via BDM, jtag, or similar hardware debug technology. There is nothing particularly original about this. Most manufacturers will provide similar utilities, and in fact those are likely to offer better performance because they operate at a lower level. The main advantages of ecoflash are: it provides a common user experience across a range of hardware; it is designed to work within a typical eCos development environment; and it has some built-in knowledge of how eCos systems work.
ecoflash works by running a suitable version of gdb
on the host machine and running gdb commands. That version of gdb must
either be able to drive the hardware debug technology directly, or
more commonly it will in turn interact with some stub or daemon that
knows how to drive the debug hardware. The target is initialized and a
small target-side executable, for example
m5213evb_flash.elf
, is then loaded on to the
target. The target-side executable is a simple eCos application that
is linked with the eCos flash driver support, so it can be readily
ported to any target for which a suitable flash driver is available.
Manipulating the flash involves setting target-side variables used gdb
commands, letting the target-side executable run until a breakpoint is
hit, and then examining more target-side variables to determine the
status.
The basic syntax is: ecoflash [standard options] subcommand [options] args [optional args]. The standard options provide information such as the target board, and most of these can be specified instead using environment variables. The subcommands specify the exact operation to be performed, for example to program an executable at the default location within the flash. Some subcommands take additional options, for example to suppress automatic erasure of flash blocks. These are followed by required arguments such as the executable filename, and possibly optional arguments. ecoflash -h with no additional argument provides help information for the utility as a whole. Additional information for a specific subcommand can be obtained using e.g. ecoflash -h program.
Standard Options
ecoflash accepts a number of standard options, for example the target
board can be specified using -b board
. These
options will be used by several but not all of the subcommands.
- -h, --help
- Obtain help information about ecoflash or one of its subcommands.
- --version
- Display the ecoflash version string.
- --dry-run
- This suppresses the low-level block erase and write operations so the flash state does not actually change, but otherwise ecoflash operates normally including initializing the board, downloading the target-side executable, and having the latter initialize the eCos flash driver. It can be used to verify that the hardware is operating correctly.
- -q, --quiet, -v, --verbose
-
These can be used to reduce or increase the amount of feedback
generated by ecoflash.
-v
can be specified several times for increased verbosity. - -b <board>, --board=<board>
ecoflash needs to know which target board it should access, so that it can perform appropriate initialization and download the right target-side executable. ecoflash boards can be used to get a list of supported boards. It is possible to set an environment variable
ECOFLASH_BOARD
as an alternative to specifying this option on the command line every time:$ export ECOFLASH_BOARD=m5213evb
The board name has two effects. It causes ecoflash to load a configuration file
<board>.ecf
with hardware-specific information, for example how to initialize the board using gdb commands. It also determines the target-side executable<board>_flash.elf
. For both files ecoflash will first look in the current directory. If anECOFLASH_DIR
environment variable is defined then it will look in that directory. Finally it will look in the directory../share/ecos/ecoflash
relative to the ecoflash executable.- -g <gdb executable>, --gdb=<gdb executable>
-
All subcommands except boards involve starting a
gdb session on the host and downloading a target-side executable.
Usually the gdb executable, for example
m68k-elf-gdb, is specified in the board
.ecf
configuration file and found in the currentPATH
, so there is no need to use this option. However an alternative gdb can be specified if desired, for example when building and debugging an experimental version of gdb. The environment variableECOFLASH_GDB
can also be used instead of the command line option. - -o <objcopy executable>, --objcopy=<objcopy executable>
-
The program subcommand can take an eCos executable
in ELF format and automatically convert it to raw binary to program
into flash. This involves running the appropriate host-side objcopy
utility, for example m68k-elf-objcopy. By default
ecoflash will munge the gdb file name to generate the objcopy name and
will look for it on the
PATH
, so there is no need to use this option. An alternative objcopy can be specified on the command line or via theECOFLASH_OBJCOPY
environment variable. - -t <target command>, --target=<target command
ecoflash needs to know how to get gdb to interact with the debug hardware. The exact details of this depend not just on the hardware but also on the developer's setup, so cannot be provided by the board
.ecf
configuration file. Instead it must be provided by the user, in the form of a gdb target command. For example, if the debug hardware is accessed via a daemon on the local machine and that daemon listens on TCP/IP port 9000 for gdb remote protocol traffic then the gdb command to connect to the target hardware would be:target remote localhost:9000
. The ecoflash-t
option should consist of everything aftertarget
, for example:$ ecoflash -b alaia -t 'remote localhost:9000' info
Note the use of quote marks to make the shell treat it as a single argument, even though it contains spaces, and to prevent any processing of special characters like $ and |. The
ECOFLASH_TARGET
environment variable can be set instead:$ export ECOFLASH_TARGET='remote localhost:9000'
Supported Boards
ecoflash boards can be used to get the names
of the boards supported in the current installation, in other words
what -b
options are valid. A board is considered
supported if ecoflash can find a
<board>.ecf
configuration file and a
target-side executable <board>_flash.elf
.
It will search in the current directory, in the directory specified by
the ECOFLASH_DIR
environment variable if that is
defined, and in a directory relative to the ecoflash executable. For
example if ecoflash is installed in /usr/local/ecos/bin
then it will search
in /usr/local/ecos/share/ecos/ecoflash
.
Note that ecoflash boards only examines the file system and does not attempt to start gdb or interact in any way with target hardware.
Board Information
ecoflash info can be used to get information about a particular board, and also to verify that everything is working correctly.
% ecoflash -b m5213evb -t 'remote localhost:9000' info Target board is m5213evb. gdb is "m68k-elf-gdb", gdb target is "remote localhost:9000" Target-side executable is version 1. Detected 1 bank of flash. Start 0x00000000, end 0x0003ffff -> 256K. 128 blocks of 2K. Flash block locking is not supported. Default program location for executables is 0x00000000. Target-side buffer for read and write operation is 16K.
This shows the gdb command and the target string, which can be useful if that information comes from environment variables rather than the command line. ecoflash will run gdb and download the target-side executable, which reports itself as version 1. The target-side executable initializes the eCos flash driver and has detected the amount of flash reported and that lock and unlock operations are not supported. By default executables will be programmed at location 0x0, and transfers between host and target use a 16k buffer (the M5213EVB only has a small amount of RAM, usually a larger buffer will be used).
Programming an Executable
ecoflash program can be used to install an eCos executable at the boot location within the flash. The executable should be linked against an eCos configuration with a suitable startup type, usually ROM or ROMRAM although this may vary between platforms. In its simplest form the subcommand just takes a single argument, a filename for the executable:
$ ecoflash program redboot.elf Erasing 0x00000000 - 0x0000be57 Writing 0x00000000 - 0x00003fff (16384 bytes) from file "/tmp/redboot.1495", offset 0 Writing 0x00004000 - 0x00007fff (16384 bytes) from file "/tmp/redboot.1495", offset 16384 Writing 0x00008000 - 0x0000be57 (15960 bytes) from file "/tmp/redboot.1495", offset 32768
This assumes the ECOFLASH_BOARD
and
ECOFLASH_TARGET
environment variables are set.
ecoflash will examine the specified file. ELF executables will be
automatically converted to a temporary raw binary file before being
programmed into flash, using the objcopy utility. The default address
within the flash is supplied by the target-side executable. Usually
this will be the processor's boot location but the exact boot
mechanism varies widely between processors and platforms.
ecoflash program takes two options.
-r
or --raw
can be used to
suppress the detection of ELF format files. Instead the file will be
treated as a raw binary and no conversion is performed. This may be
useful if the board has its own primary bootloader which expects to
find an ELF executable at a particular address within the flash.
-n
or --no-erase
can be used to
suppress the automatic erase of the flash blocks prior to programming
the flash. This may be useful on hardware where flash erase is
optional, or if ecoflash is used in a batch environment where a
previous step will have already erased the required amount of flash.
ecoflash program takes an optional additional argument, an alternative address within the flash. This may be useful if for example the board can boot from one of two locations depending on the state of a jumper.
Dumping Flash Contents
ecoflash dump can be used to read part or all of the flash and dump the data to a file on the host. This can be particularly useful when saving a known working image prior to replacing it with an experimental version. The default behaviour is to dump the entire flash contents:
$ ecoflash dump /tmp/working.bin Dumping 0x00000000 - 0x00003fff (16384 bytes) to file "/tmp/working.bin" Dumping 0x00004000 - 0x00007fff (16384 bytes) to file "/tmp/working.bin" …
Optionally the starting address and the length can be specified:
$ ecoflash dump /tmp/working.bin 0xFFF00000 128K
Lengths can be specified in bytes, kilobytes using a K suffix, megabytes using an M suffix, or flash blocks using a B suffix. Note that some flash devices have boot blocks of varying sizes so specifying a size in terms of blocks can be confusing.
ecoflash dump takes a single option,
-a
or --append
. This causes
ecoflash to append to the specified file instead of overwriting it.
Erasing Flash Blocks
ecoflash erase can be used to erase one or more flash blocks. This command is rarely needed since both the program and write subcommands will erase the required number of flash blocks by default, but may prove useful if the flash contains data other than an eCos executable and that data should be reset to uninitialized. In its simplest form the erase subcommand just takes an address:
$ ecoflash erase 0x40000
This causes ecoflash to erase the single flash block containing the specified address. Optionally a length can be specified, for example to erase 8 flash blocks:
$ ecoflash erase 0x40000 8B
The length can be specified in bytes, in kilobytes using a K suffix, in megabytes using an M suffix, or in flash blocks using a B suffix. Care must be taken if the specified address is not at the start of a flash block. For example if the address is 0x48000, the length is 128K, and flash blocks are 64K, then this is treated as a request to erase flash from 0x48000 to 0x67FFF. Since erase operations always involve whole flash blocks the actual erase affects all memory from 0x40000 to 0x6FFFF, so a total of 192K gets erased.
The erase subcommand does not have any options of its own, just the standard ones for all subcommands.
Writing Raw Data
ecoflash write can be used to write a raw data file to an arbitrary location within the flash. It is intended for installing additional data rather than the main executable, since the program subcommand is more appropriate for the latter. At least a filename and an address within the flash should be specified:
$ ecoflash write data.bin 0x00040000 Erasing 0x00040000 - 0x0004297c Writing 0x00040000 - 0x0004297c (10621 bytes) from file "data.bin", offset 0
Optionally a length can be specified, for example:
$ ecoflash write data.bin 0x00040000 64K
This will write only the first 64K of data.bin rather than the whole file. The length can be specified in bytes, in kilobytes using a K suffix, in megabytes using an M suffix, or in flash blocks using a B suffix.
ecoflash write takes two options.
-n
or --no-erase
can be used to
suppress the automatic erase before the data is written to flash. This
can be useful if a single flash block should contain data from more
than one file: ecoflash erase would be
used to erase the whole flash black, then two
ecoflash write -n commands would program
the two files at the appropriate locations; alternatively the erase
step can be skipped in subsumed by the first write, with only the
second write using a -n
option.
-o <offset>
or
-offset=<offset>
can be used to skip part of
a file. For example the following writes 12K of a file starting at a
4K offset:
$ ecoflash write --offset=4096 data.bin 12K
The offset can be specified in bytes, kilobytes using a K suffix, or megabytes using an M suffix.
Locking and Unlocking
On targets where the hardware and the flash driver support locking, the lock and unlock subcommands can be used to manipulate the locked status of one or more flash blocks. Both subcommands take an address and an optional length:
$ ecoflash lock 0x40000 … $ ecoflash unlock 0x50000 256K
If no length is specified then just a single flash block is affected, unless the hardware implements locking at a coarser grain than individual flash blocks. The length can be specified in bytes, in kilobytes using a K suffix, in megabytes using an M suffix, or in flash blocks using a B suffix.
With some flash hardware locking is not persistent. Instead the locks are set to a default state when the flash chips are powered up or reset, usually locked. On such hardware the ecoflash lock and unlock subcommands are of little use since the locks would revert to their default state when ecoflash exits. Instead the target-side executable will either unlock all flash blocks during initialization or take whatever action is needed at run-time to handle erase and write operations.
Installation
Depending on your eCos distribution ecoflash may already be installed
on your system. If not, installation is straightforward. The host-side
consists of a single executable ecoflash
in the
package's host
subdirectory.
This is actually a platform-independent script written in the expect
scripting language. It needs to be installed in a suitable location
on the user's search PATH
. The file can just be copied
manually, or alternatively the host
subdirectory contains a suitable
configure script and support files:
$ <package path>/host/configure --prefix=/usr/local $ make $ make install
This will install ecoflash in the directory /usr/local/bin
. Note that eCos also has a
top-level configure
script which will find
subsidiary configure
scripts inside the
individual packages. A top-level configure/make/make install
sequence will automatically install ecoflash as well as host-side
support from other packages.
The ecoflash package contains only the generic support. It should be
complemented by a .ecf
configuration file and a
_flash.elf
target-side executable for every
supported platform. The platform HAL's misc
subdirectory usually holds a
suitable .ecf
file. The target-side executable
will need to be rebuilt:
$ ecosconfig new <target> minimal $ ecosconfig import <path>/ecoflash.ecm $ ecosconfig tree $ make
For an existing port there should be an
ecoflash.ecm
file in the platform HAL's misc
subdirectory. Importing this will add the ecoflash package and any
necessary support packages, set any platform-specific configuration
options, and resolve any conflicts. After the make there should be a
file install/bin/flash.elf
, the target-side
executable, and this should get renamed to
<board>_flash.elf
and installed in a
location where ecoflash will find it.
Porting
Typically the only hard part of porting ecoflash to a new platform is
to get gdb to interact with the jtag or BDM hardware and initialize
the board. The porting process involves three steps: adding appropriate
definitions to the platform HAL; building the target-side executable
<board>_flash.elf
; and writing the platform
configuration file <board>.ecf
.
The platform HAL must supply a single #define'd symbol corresponding
to the default base address for
ecoflash program operations. Usually this
symbol gets defined in cyg/hal/plf_io.h
, but the details may
vary between architectures.
#define HAL_ECOFLASH_PROGRAM_BASE 0x00000000
Optionally the platform HAL can define a buffer size using
HAL_ECOFLASH_BUFLEN
, an additional header file to
include using HAL_ECOFLASH_HEADER
, and an
initialization macro HAL_ECOFLASH_EXTRA_INIT()
.
The latter may perform operations such as unlocking all flash blocks
on hardware where locks are transient.
The target-side executable is a very simple eCos application that uses the generic flash driver support to interact with the the hardware. Hence it assumes that a suitable flash driver is already available. Code and data sizes are both of the order of 4K, although obviously that will depend on the processor architecture. Usually the code will be RAM-resident and linked with a JTAG or RAM startup configuration. In addition a buffer is needed for transferring data between host and target. By default that buffer is 64K, corresponding to typical flash block sizes, but can be smaller if there is not enough RAM for a buffer that size. Building the target-side executable is straightforward:
$ ecosconfig new <target> minimal $ ecosconfig add CYGPKG_IO_FLASH CYGPKG_LIBC_STRING CYGPKG_ECOFLASH $ ecosconfig resolve $ ecosconfig tree $ make
It may be necessary to tweak the configuration data before generating the build tree, for example to change the startup type to JTAG or RAM. Adding the ecoflash package will result in one conflict related to the global compiler flags: by default ecoflash is built with no eCos debugging information, except for the ecoflash application itself. The target-side executable may get checked into the source code control system as a binary, so avoiding debug information helps to keep the size down. Stripping out all debug information after the build is not possible because it would interfere with some of the gdb commands that ecoflash uses to interact with the target.
The result of the make is an executable flash.elf
in the install/bin
subdirectory. This should get renamed to
<target>_flash.elf
and installed to a
directory where ecoflash will find it. Optionally an
ecoflash.ecm
file containing the configuration
settings can be exported to facilitate future rebuilding.
Next it is necessary to write the configuration file
<target>.ecf
. This is a straightforward
expect script that gets included by the main ecoflash executable. It
should set variables ::gdb_executable
and
::command_prefix
. Optionally it may also define
procedures target_init0
,
target_init1
, and
target_kill
. target_init0
is
invoked after gdb has been started but before the gdb target command
has been issued. target_init1
is invoked after
the gdb target command has been issued, and typically takes care of
initializing the board via a sequence of gdb commands. To facilitate
this the main ecoflash script provides procedures gdb_run_command and
gdb_run_quiet_command which will do the hard work.
target_kill
is invoked just before shutting down
the gdb session. The <target>.ecf
file is
typically placed in the platform HAL's misc
subdirectory.
2024-03-18 | eCosPro Non-Commercial Public License |