target: Add calculate_checksum command

This command allows to calculate the checksum of a memory region to
verify its contents against a known value. Unlike 'verify_image_checksum',
this command requires no file and accepts arbitrary memory addresses and
sizes.

Change-Id: I0f7309999bc7268e58af533695bcfaa3c1a5fc24
Signed-off-by: Marc Schink <[email protected]>
Reviewed-on: https://review.openocd.org/c/openocd/+/9971
Reviewed-by: Antonio Borneo <[email protected]>
Tested-by: jenkins
Reviewed-by: Tomas Vanek <[email protected]>
This commit is contained in:
Marc Schink
2026-09-20 13:44:25 +00:00
committed by Antonio Borneo
parent a3277510b3
commit b04ccfeff7
2 changed files with 80 additions and 0 deletions
+37
View File
@@ -5605,6 +5605,36 @@ read_memory 0x20000000 32 2
@end example
@end deffn
@anchor{target_calculate_checksum}
@deffn {Command} {$target_name calculate_checksum} address size
Calculates the checksum of the memory region starting at @var{address} with a
length of @var{size}.
The checksum algorithm uses a 32-bit cyclic redundancy check (CRC) with the
polynomial @code{0x04c11db7} and an initial seed of @code{0xffffffff}. There is
no input or output reflection, and the XOR output mask is @code{0x00000000}.
If available, the checksum is calculated on the target device using a loader
function executed in the working area. This accelerates the calculation and
avoids transferring the memory contents to the host.
For example, to calculate the checksum of 1 KiB starting at address
@code{0x08000000}, use the following command:
@example
calculate_checksum 0x08000000 1024
0x4fae1a88
@end example
In Python, for example, the checksum for verification can be calculated as
follows:
@example
from crccheck.crc import Crc32Mpeg2
data = b'deadbeef'
checksum = Crc32Mpeg2.calc(data, initvalue=0xffffffff)
@end example
@end deffn
@deffn {Command} {$target_name cget} queryparm
Each configuration parameter accepted by
@command{$target_name configure}
@@ -10340,6 +10370,13 @@ Returns current time since the Epoch in ms
Useful to compute delays in Tcl.
@end deffn
@deffn {Command} {calculate_checksum} address size
Calculates the checksum of the memory region starting at @var{address} with a
length of @var{size}.
@xref{target_calculate_checksum,, $target_name calculate_checksum} for more details.
@end deffn
@node Architecture and Core Commands
@chapter Architecture and Core Commands
@cindex Architecture Specific Commands
+43
View File
@@ -3939,6 +3939,37 @@ COMMAND_HANDLER(handle_test_image_command)
return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, IMAGE_TEST);
}
COMMAND_HANDLER(handle_calculate_checksum_command)
{
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
struct target *target = get_current_target_or_null(CMD_CTX);
if (!target) {
command_print(CMD, "no target selected");
return ERROR_FAIL;
}
target_addr_t address;
COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);
uint32_t length;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
uint32_t checksum;
int retval = target_checksum_memory(target, address, length, &checksum);
if (retval != ERROR_OK) {
command_print(CMD, "checksum calculation failed");
return retval;
}
command_print(CMD, "0x%" PRIx32, checksum);
return ERROR_OK;
}
static int handle_bp_command_list(struct command_invocation *cmd)
{
struct target *target = get_current_target(cmd->ctx);
@@ -5707,6 +5738,12 @@ static const struct command_registration target_instance_command_handlers[] = {
.help = "Write Tcl list of 8/16/32/64 bit numbers to target memory",
.usage = "address width data ['phys']",
},
{
.name = "calculate_checksum",
.handler = handle_calculate_checksum_command,
.mode = COMMAND_EXEC,
.usage = "address size",
},
{
.name = "eventlist",
.handler = handle_target_event_list,
@@ -6841,6 +6878,12 @@ static const struct command_registration target_exec_command_handlers[] = {
.help = "Write Tcl list of 8/16/32/64 bit numbers to target memory",
.usage = "address width data ['phys']",
},
{
.name = "calculate_checksum",
.handler = handle_calculate_checksum_command,
.mode = COMMAND_EXEC,
.usage = "address size",
},
{
.name = "debug_reason",
.mode = COMMAND_EXEC,